summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorABU MD. MARUF SARKER <maruf.devel@gmail.com>2017-09-19 10:09:35 +0600
committerABU MD. MARUF SARKER <maruf.devel@gmail.com>2017-09-20 08:20:08 +0600
commit7744bb153f222c0343d587e5cb11cf6f19172634 (patch)
treea570d647c0d3dd37a1c8ce43f4cfae35b8ecc7fb
parentcd2ffdc6725aa6f7a9a4af6fd5abcc4cafae61b4 (diff)
verbose and platform specific implementation for is_nan
-rw-r--r--core/math/math_funcs.h40
1 files changed, 38 insertions, 2 deletions
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 9651e37f3e..d63da322a5 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -104,8 +104,44 @@ public:
static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); }
static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); }
- static _ALWAYS_INLINE_ bool is_nan(double p_val) { return (p_val != p_val); }
- static _ALWAYS_INLINE_ bool is_nan(float p_val) { return (p_val != p_val); }
+ static _ALWAYS_INLINE_ bool is_nan(double p_val) {
+#ifdef _MSC_VER
+ return _isnan(p_val);
+#elif defined(__GNUC__) && __GNUC__ < 6
+ union {
+ uint64_t u;
+ double f;
+ } ieee754;
+ ieee754.f = p_val;
+ // (unsigned)(0x7ff0000000000001 >> 32) : 0x7ff00000
+ return ((((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0)) > 0x7ff00000);
+#else
+ return isnan(p_val);
+#endif
+ }
+
+ static _ALWAYS_INLINE_ bool is_nan(float p_val) {
+#ifdef _MSC_VER
+ return _isnan(p_val);
+#elif defined(__GNUC__) && __GNUC__ < 6
+ union {
+ uint32_t u;
+ float f;
+ } ieee754;
+ ieee754.f = p_val;
+ // -----------------------------------
+ // (single-precision floating-point)
+ // NaN : s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
+ // : (> 0x7f800000)
+ // where,
+ // s : sign
+ // x : non-zero number
+ // -----------------------------------
+ return ((ieee754.u & 0x7fffffff) > 0x7f800000);
+#else
+ return isnan(p_val);
+#endif
+ }
static _ALWAYS_INLINE_ bool is_inf(double p_val) {
#ifdef _MSC_VER