summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-12-11 02:01:43 -0800
committerGitHub <noreply@github.com>2020-12-11 11:01:43 +0100
commit0b73106ccf983565d34654ee8b1167827b53b01a (patch)
tree2077391acd95abccf408cc832b466f3dcc3dee34 /lib
parentbb1c962286922487c5243ca7304fd95fdd27ea53 (diff)
downloadNim-0b73106ccf983565d34654ee8b1167827b53b01a.tar.gz
add math.isNaN (#16179)
* add math.isNaN
* isNaN now works with --passc:-ffast-math; tests
* Update lib/pure/math.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/js/dom.nim1
-rw-r--r--lib/pure/math.nim21
2 files changed, 22 insertions, 0 deletions
diff --git a/lib/js/dom.nim b/lib/js/dom.nim
index b73a85291..b74a58a1a 100644
--- a/lib/js/dom.nim
+++ b/lib/js/dom.nim
@@ -1683,6 +1683,7 @@ proc decodeURIComponent*(uri: cstring): cstring {.importc, nodecl.}
 proc encodeURIComponent*(uri: cstring): cstring {.importc, nodecl.}
 proc isFinite*(x: BiggestFloat): bool {.importc, nodecl.}
 proc isNaN*(x: BiggestFloat): bool {.importc, nodecl.}
+  ## see also `math.isNaN`.
 
 proc newEvent*(name: cstring): Event {.importcpp: "new Event(@)", constructor.}
 
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index b2433d309..5f3261f1a 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -58,6 +58,10 @@ import std/private/since
 
 import bitops, fenv
 
+when defined(c) or defined(cpp):
+  proc c_isnan(x: float): bool {.importc: "isnan", header: "<math.h>".}
+    # a generic like `x: SomeFloat` might work too if this is implemented via a C macro.
+
 func binom*(n, k: int): int =
   ## Computes the `binomial coefficient <https://en.wikipedia.org/wiki/Binomial_coefficient>`_.
   runnableExamples:
@@ -133,10 +137,27 @@ type
     fcInf,           ## value is positive infinity
     fcNegInf         ## value is negative infinity
 
+func isNaN*(x: SomeFloat): bool {.inline, since: (1,5,1).} =
+  ## Returns whether `x` is a `NaN`, more efficiently than via `classify(x) == fcNan`.
+  ## Works even with: `--passc:-ffast-math`.
+  runnableExamples:
+    doAssert NaN.isNaN
+    doAssert not Inf.isNaN
+    doAssert isNaN(Inf - Inf)
+    doAssert not isNan(3.1415926)
+    doAssert not isNan(0'f32)
+
+  template fn: untyped = result = x != x
+  when nimvm: fn()
+  else:
+    when defined(js): fn()
+    else: result = c_isnan(x)
+
 func classify*(x: float): FloatClass =
   ## Classifies a floating point value.
   ##
   ## Returns ``x``'s class as specified by `FloatClass enum<#FloatClass>`_.
+  ## Doesn't work with: `--passc:-ffast-math`.
   runnableExamples:
     doAssert classify(0.3) == fcNormal
     doAssert classify(0.0) == fcZero