summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorflywind <43030857+xflywind@users.noreply.github.com>2021-01-01 03:59:19 -0600
committerGitHub <noreply@github.com>2021-01-01 10:59:19 +0100
commit9d4a1f95544c6c7c58829384cf8045e3803faab0 (patch)
treee505280788fbaff5b3d1489439de6c7ddca1a9b4
parent5fb56a3b2c83b62d72c72a9d56ef1333671bc2b6 (diff)
downloadNim-9d4a1f95544c6c7c58829384cf8045e3803faab0.tar.gz
fix #16494 (#16513)
* fix #16494

* fix

* fix

* fix

* fix

* fix

* fix performance

* add comments

* improve performance

* Update lib/system.nim

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

* Update lib/system.nim

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

* Update tests/stdlib/tmath_misc.nim

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

* Update tests/stdlib/tmath_misc.nim

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
-rw-r--r--lib/system.nim24
-rw-r--r--tests/stdlib/tmath_misc.nim24
2 files changed, 44 insertions, 4 deletions
diff --git a/lib/system.nim b/lib/system.nim
index b6f7d655a..29c137b63 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1522,10 +1522,26 @@ include "system/iterators_1"
 
 {.push stackTrace: off.}
 
-proc abs*(x: float64): float64 {.noSideEffect, inline.} =
-  if x < 0.0: -x else: x
-proc abs*(x: float32): float32 {.noSideEffect, inline.} =
-  if x < 0.0: -x else: x
+
+when defined(js):
+  proc js_abs[T: SomeNumber](x: T): T {.importc: "Math.abs".}
+else:
+  proc c_fabs(x: cdouble): cdouble {.importc: "fabs", header: "<math.h>".}
+  proc c_fabsf(x: cfloat): cfloat {.importc: "fabsf", header: "<math.h>".}
+
+proc abs*[T: float64 | float32](x: T): T {.noSideEffect, inline.} =
+  when nimvm:
+    if x < 0.0: result = -x
+    elif x == 0.0: result = 0.0 # handle 0.0, -0.0
+    else: result = x # handle NaN, > 0
+  else:
+    when defined(js): result = js_abs(x)
+    else:
+      when T is float64:
+        result = c_fabs(x)
+      else:
+        result = c_fabsf(x)
+
 proc min*(x, y: float32): float32 {.noSideEffect, inline.} =
   if x <= y or y != y: x else: y
 proc min*(x, y: float64): float64 {.noSideEffect, inline.} =
diff --git a/tests/stdlib/tmath_misc.nim b/tests/stdlib/tmath_misc.nim
new file mode 100644
index 000000000..978e3e94d
--- /dev/null
+++ b/tests/stdlib/tmath_misc.nim
@@ -0,0 +1,24 @@
+discard """
+  targets: "c js"
+"""
+
+# TODO merge this to tmath.nim once tmath.nim supports js target
+
+import math
+
+proc main() =
+  block:
+    doAssert 1.0 / abs(-0.0) == Inf
+    doAssert 1.0 / abs(0.0) == Inf
+    doAssert -1.0 / abs(-0.0) == -Inf
+    doAssert -1.0 / abs(0.0) == -Inf
+    doAssert abs(0.0) == 0.0
+    doAssert abs(0.0'f32) == 0.0'f32
+
+    doAssert abs(Inf) == Inf
+    doAssert abs(-Inf) == Inf
+    doAssert abs(NaN).isNaN
+    doAssert abs(-NaN).isNaN
+
+static: main()
+main()