add euclDiv and euclMod to math (#16414)

* add `euclDiv` and `euclMod` to `math`
* use abs
* Update lib/pure/math.nim

Co-authored-by: Clyybber <darkmine956@gmail.com>
This commit is contained in:
flywind
2020-12-23 05:04:38 -06:00
committed by GitHub
parent 417c2509c4
commit b1c3dab208
3 changed files with 56 additions and 0 deletions

View File

@@ -73,6 +73,8 @@
- Added `sequtils` import to `prelude`.
- Added `euclDiv` and `euclMod` to `math`.
## Language changes
- `nimscript` now handles `except Exception as e`.

View File

@@ -882,6 +882,32 @@ func floorMod*[T: SomeNumber](x, y: T): T =
result = x mod y
if (result > 0 and y < 0) or (result < 0 and y > 0): result += y
func euclDiv*[T: SomeInteger](x, y: T): T {.since: (1, 5, 1).} =
## Returns euclidean division of `x` by `y`.
runnableExamples:
assert euclDiv(13, 3) == 4
assert euclDiv(-13, 3) == -5
assert euclDiv(13, -3) == -4
assert euclDiv(-13, -3) == 5
result = x div y
if x mod y < 0:
if y > 0:
dec result
else:
inc result
func euclMod*[T: SomeNumber](x, y: T): T {.since: (1, 5, 1).} =
## Returns euclidean modulo of `x` by `y`.
## `euclMod(x, y)` is non-negative.
runnableExamples:
assert euclMod(13, 3) == 1
assert euclMod(-13, 3) == 2
assert euclMod(13, -3) == 1
assert euclMod(-13, -3) == 2
result = x mod y
if result < 0:
result += abs(y)
when not defined(js):
func c_frexp*(x: float32, exponent: var int32): float32 {.
importc: "frexp", header: "<math.h>".}

View File

@@ -270,6 +270,34 @@ block:
doAssert floorMod(8.0, -3.0) ==~ -1.0
doAssert floorMod(-8.5, 3.0) ==~ 0.5
block: # euclDiv/euclMod
doAssert euclDiv(8, 3) == 2
doAssert euclMod(8, 3) == 2
doAssert euclDiv(8, -3) == -2
doAssert euclMod(8, -3) == 2
doAssert euclDiv(-8, 3) == -3
doAssert euclMod(-8, 3) == 1
doAssert euclDiv(-8, -3) == 3
doAssert euclMod(-8, -3) == 1
doAssert euclMod(8.0, -3.0) ==~ 2.0
doAssert euclMod(-8.5, 3.0) ==~ 0.5
doAssert euclDiv(9, 3) == 3
doAssert euclMod(9, 3) == 0
doAssert euclDiv(9, -3) == -3
doAssert euclMod(9, -3) == 0
doAssert euclDiv(-9, 3) == -3
doAssert euclMod(-9, 3) == 0
doAssert euclDiv(-9, -3) == 3
doAssert euclMod(-9, -3) == 0
block: # log
doAssert log(4.0, 3.0) ==~ ln(4.0) / ln(3.0)
doAssert log2(8.0'f64) == 3.0'f64