summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2013-03-21 23:56:19 -0400
committerErik Schnetter <schnetter@gmail.com>2013-03-21 23:56:19 -0400
commit426f02cd14671a15424420adb9ba5735780e1c97 (patch)
tree9171b6357b8ca2d406405480f3c544316ae8e17c
parent9420f154df04f53c85720cfed3262bb67a040f0d (diff)
downloadvecmathlib-426f02cd14671a15424420adb9ba5735780e1c97.zip
vecmathlib-426f02cd14671a15424420adb9ba5735780e1c97.tar.gz
Correct ilogb(0)
-rw-r--r--test.cc8
-rw-r--r--vec_double_sse2_scalar.h8
-rw-r--r--vec_float_sse2_scalar.h8
-rw-r--r--vec_pseudo.h7
4 files changed, 27 insertions, 4 deletions
diff --git a/test.cc b/test.cc
index 818b23a..86078c5 100644
--- a/test.cc
+++ b/test.cc
@@ -371,7 +371,13 @@ struct vecmathlib_test {
}
// Change signature: "int" -> "int_t"
- static int_t ilogb(real_t x) { return std::ilogb(x); }
+ static int_t ilogb(real_t x)
+ {
+ int r = std::ilogb(x);
+ if (r==FP_ILOGB0) return numeric_limits<int_t>::min();
+ if (r==FP_ILOGBNAN) return numeric_limits<int_t>::max();
+ return r;
+ }
static real_t ldexp(real_t x, int_t n) { return std::ldexp(x, n); }
static void test_fabs()
{
diff --git a/vec_double_sse2_scalar.h b/vec_double_sse2_scalar.h
index 70f94e1..66b1398 100644
--- a/vec_double_sse2_scalar.h
+++ b/vec_double_sse2_scalar.h
@@ -396,7 +396,13 @@ namespace vecmathlib {
}
realvec fmod(realvec y) const { return std::fmod(v, y.v); }
realvec hypot(realvec y) const { return MF::vml_hypot(*this, y); }
- intvec_t ilogb() const { return std::ilogb(v); }
+ intvec_t ilogb() const
+ {
+ int_t r = std::ilogb(v);
+ if (r == FP_ILOGB0) r = numeric_limits<int_t>::min();
+ else if (r == FP_ILOGBNAN) r = numeric_limits<int_t>::max();
+ return r;
+ }
boolvec_t isfinite() const { return std::isfinite(v); }
boolvec_t isinf() const { return std::isinf(v); }
boolvec_t isnan() const { return std::isnan(v); }
diff --git a/vec_float_sse2_scalar.h b/vec_float_sse2_scalar.h
index e39a324..def48fa 100644
--- a/vec_float_sse2_scalar.h
+++ b/vec_float_sse2_scalar.h
@@ -396,7 +396,13 @@ namespace vecmathlib {
}
realvec fmod(realvec y) const { return std::fmod(v, y.v); }
realvec hypot(realvec y) const { return MF::vml_hypot(*this, y); }
- intvec_t ilogb() const { return std::ilogb(v); }
+ intvec_t ilogb() const
+ {
+ int_t r = std::ilogb(v);
+ if (r == FP_ILOGB0) r = numeric_limits<int_t>::min();
+ else if (r == FP_ILOGBNAN) r = numeric_limits<int_t>::max();
+ return r;
+ }
boolvec_t isfinite() const { return std::isfinite(v); }
boolvec_t isinf() const { return std::isinf(v); }
boolvec_t isnan() const { return std::isnan(v); }
diff --git a/vec_pseudo.h b/vec_pseudo.h
index 31d9cbb..ad3a70c 100644
--- a/vec_pseudo.h
+++ b/vec_pseudo.h
@@ -680,7 +680,12 @@ namespace vecmathlib {
intvec_t ilogb() const
{
intvec_t res;
- for (int d=0; d<size; ++d) res.v[d] = std::ilogb(v[d]);
+ for (int d=0; d<size; ++d) {
+ int_t r = std::ilogb(v[d]);
+ if (r == FP_ILOGB0) r = numeric_limits<int_t>::min();
+ else if (r == FP_ILOGBNAN) r = numeric_limits<int_t>::max();
+ res.v[d] = r;
+ }
return res;
}
boolvec_t isfinite() const { return mapb(std::isfinite); }
OpenPOWER on IntegriCloud