summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2017-09-20 14:29:01 +0200
committerGitHub <noreply@github.com>2017-09-20 14:29:01 +0200
commite3617cb18771232876b1318639adb7dc9c5f452b (patch)
tree173ec50ab11a32975bde882963eebf28799fc1e1 /core
parent372cdc20705dab7c2227b89d8bc4d425ffd3e8a4 (diff)
parent7744bb153f222c0343d587e5cb11cf6f19172634 (diff)
Merge pull request #11409 from MarufSarker/PR-core-math-is_nan
Verbose and Platform-specific implementation for is_nan
Diffstat (limited to 'core')
-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