diff options
author | Erik Schnetter <schnetter@gmail.com> | 2013-03-21 23:56:19 -0400 |
---|---|---|
committer | Erik Schnetter <schnetter@gmail.com> | 2013-03-21 23:56:19 -0400 |
commit | 426f02cd14671a15424420adb9ba5735780e1c97 (patch) | |
tree | 9171b6357b8ca2d406405480f3c544316ae8e17c | |
parent | 9420f154df04f53c85720cfed3262bb67a040f0d (diff) | |
download | vecmathlib-426f02cd14671a15424420adb9ba5735780e1c97.zip vecmathlib-426f02cd14671a15424420adb9ba5735780e1c97.tar.gz |
Correct ilogb(0)
-rw-r--r-- | test.cc | 8 | ||||
-rw-r--r-- | vec_double_sse2_scalar.h | 8 | ||||
-rw-r--r-- | vec_float_sse2_scalar.h | 8 | ||||
-rw-r--r-- | vec_pseudo.h | 7 |
4 files changed, 27 insertions, 4 deletions
@@ -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); } |