diff options
-rw-r--r-- | changelog.md | 5 | ||||
-rw-r--r-- | lib/pure/math.nim | 12 | ||||
-rw-r--r-- | tests/stdlib/tmath.nim | 30 |
3 files changed, 40 insertions, 7 deletions
diff --git a/changelog.md b/changelog.md index b97fcdd03..306cf54d3 100644 --- a/changelog.md +++ b/changelog.md @@ -84,13 +84,14 @@ - Added `mimetypes.mimesExtMaxLen` thats equal to the length of the longest "ext" from `mimes`. - Added `mimetypes.mimesMaxLen` thats equal to the length of the longest "mime" from `mimes`. - - - Added `posix_utils.osReleaseFile` to get system identification from `os-release` file on Linux and the BSDs. https://www.freedesktop.org/software/systemd/man/os-release.html - Added `BackwardsIndex` overload for `JsonNode`. +- `math.round` now is rounded "away from zero" in JS backend which is consistent +with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior. + ## Language changes diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 76052ec3b..a6a3676b9 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -847,7 +847,17 @@ else: # JS func floor*(x: float64): float64 {.importc: "Math.floor", nodecl.} func ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.} func ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.} - func round*(x: float): float {.importc: "Math.round", nodecl.} + + when (NimMajor, NimMinor) < (1, 5) or defined(nimLegacyJsRound): + func round*(x: float): float {.importc: "Math.round", nodecl.} + else: + func jsRound(x: float): float {.importc: "Math.round", nodecl.} + func round*[T: float64 | float32](x: T): T = + if x >= 0: result = jsRound(x) + else: + result = ceil(x) + if result - x >= T(0.5): + result -= T(1.0) func trunc*(x: float32): float32 {.importc: "Math.trunc", nodecl.} func trunc*(x: float64): float64 {.importc: "Math.trunc", nodecl.} diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim index fbc6b80ad..e5cb58eba 100644 --- a/tests/stdlib/tmath.nim +++ b/tests/stdlib/tmath.nim @@ -10,6 +10,10 @@ import std/[math, random, os] import std/[unittest] import std/[sets, tables] + +# Function for approximate comparison of floats +proc `==~`(x, y: float): bool = (abs(x-y) < 1e-9) + block: # random int block: # there might be some randomness var set = initHashSet[int](128) @@ -158,10 +162,6 @@ block: doAssert(erf(6.0) > erf(5.0)) doAssert(erfc(6.0) < erfc(5.0)) - proc `==~`(x, y: float): bool = (abs(x-y) < 1e-9) - # Function for approximate comparison of floats - # xxx use `almostEqual` - block: # prod doAssert prod([1, 2, 3, 4]) == 24 doAssert prod([1.5, 3.4]).almostEqual 5.1 @@ -349,6 +349,28 @@ template main = doAssert copySign(-NaN, 0.0).isNaN doAssert copySign(-NaN, -0.0).isNaN + block: # round() tests + # Round to 0 decimal places + doAssert round(54.652) == 55.0 + doAssert round(54.352) == 54.0 + doAssert round(-54.652) == -55.0 + doAssert round(-54.352) == -54.0 + doAssert round(0.0) == 0.0 + doAssert 1 / round(0.0) == Inf + doAssert 1 / round(-0.0) == -Inf + doAssert round(Inf) == Inf + doAssert round(-Inf) == -Inf + doAssert round(NaN).isNaN + doAssert round(-NaN).isNaN + doAssert round(-0.5) == -1.0 + doAssert round(0.5) == 1.0 + doAssert round(-1.5) == -2.0 + doAssert round(1.5) == 2.0 + doAssert round(-2.5) == -3.0 + doAssert round(2.5) == 3.0 + doAssert round(2.5'f32) == 3.0'f32 + doAssert round(2.5'f64) == 3.0'f64 + when nimvm: discard else: |