diff options
author | Ryan McConnell <rammcconnell@gmail.com> | 2023-06-20 07:04:34 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-20 13:04:34 +0200 |
commit | db41f04ab0734b0ac5267b46f306b0a311f7fc71 (patch) | |
tree | 3ceaa2f63c45bfd498f7fa3c747b6c813a6b7c0e | |
parent | f524d60fa1e1c3a3722632e2a01bf93c6cb02e88 (diff) | |
download | Nim-db41f04ab0734b0ac5267b46f306b0a311f7fc71.tar.gz |
Amend divmod (#22131)
* Add Overflow checks & test adjust * Avoiding nimvm differences in tests * distinguish DivByZeroDefect
-rw-r--r-- | lib/pure/math.nim | 7 | ||||
-rw-r--r-- | tests/stdlib/tmath.nim | 15 |
2 files changed, 17 insertions, 5 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 7ed84fa71..4bc720a46 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -101,6 +101,11 @@ when defined(c) or defined(cpp): doAssert divmod(5, 2) == (2, 1) doAssert divmod(5, -3) == (-1, 2) when T is cint | clong | clonglong: + when compileOption("overflowChecks"): + if y == 0: + raise new(DivByZeroDefect) + elif (x == T.low and y == -1.T): + raise new(OverflowDefect) let res = divmod_c(x, y) result[0] = res.quot result[1] = res.rem @@ -824,7 +829,7 @@ else: # JS doAssert 6.5 mod -2.5 == 1.5 doAssert -6.5 mod -2.5 == -1.5 - func divmod*(num, denom: int): (int, int) = + func divmod*[T:SomeInteger](num, denom: T): (T, T) = runnableExamples: doAssert divmod(5, 2) == (2, 1) doAssert divmod(5, -3) == (-1, 2) diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim index 3fcc42ae8..22e5f7d88 100644 --- a/tests/stdlib/tmath.nim +++ b/tests/stdlib/tmath.nim @@ -190,10 +190,17 @@ template main() = block: # divmod doAssert divmod(int.high, 1) == (int.high, 0) doAssert divmod(-1073741823, 17) == (-63161283, -12) - when not defined(js): - doAssert divmod(int32.high, 1.int32) == (int32.high, 0.int32) - doAssert divmod(1073741823.int32, 5.int32) == (214748364.int32, 3.int32) - doAssert divmod(4611686018427387903.int64, 5.int64) == (922337203685477580.int64, 3.int64) + doAssert divmod(int32.high, 1.int32) == (int32.high, 0.int32) + doAssert divmod(1073741823.int32, 5.int32) == (214748364.int32, 3.int32) + doAssert divmod(4611686018427387903.int64, 5.int64) == (922337203685477580.int64, 3.int64) + when not defined(js) and (not compileOption("panics")) and compileOption("overflowChecks"): + when nimvm: + discard # cannot catch OverflowDefect here + else: + doAssertRaises(OverflowDefect, (discard divmod(cint.low, -1.cint))) + doAssertRaises(OverflowDefect, (discard divmod(clong.low, -1.clong))) + doAssertRaises(OverflowDefect, (discard divmod(clonglong.low, -1.clonglong))) + doAssertRaises(DivByZeroDefect, (discard divmod(1, 0))) block: # log doAssert log(4.0, 3.0) ==~ ln(4.0) / ln(3.0) |