Support div, mod, floorDiv and floorMod for Rationals (#7918)
* Support `div`, `mod`, floorDiv and floorMod for Ratinoals. * Bug fix and add tests. * Update changelog
This commit is contained in:
parent
829f89d649
commit
3027ca292c
2 changed files with 37 additions and 0 deletions
|
|
@ -64,6 +64,7 @@
|
||||||
- Added inverse hyperbolic functions, ``math.arcsinh``, ``math.arccosh`` and ``math.arctanh`` procs.
|
- Added inverse hyperbolic functions, ``math.arcsinh``, ``math.arccosh`` and ``math.arctanh`` procs.
|
||||||
- Added cotangent, secant and cosecant procs ``math.cot``, ``math.sec`` and ``math.csc``; and their hyperbolic, inverse and inverse hyperbolic functions, ``math.coth``, ``math.sech``, ``math.csch``, ``math.arccot``, ``math.arcsec``, ``math.arccsc``, ``math.arccoth``, ``math.arcsech`` and ``math.arccsch`` procs.
|
- Added cotangent, secant and cosecant procs ``math.cot``, ``math.sec`` and ``math.csc``; and their hyperbolic, inverse and inverse hyperbolic functions, ``math.coth``, ``math.sech``, ``math.csch``, ``math.arccot``, ``math.arcsec``, ``math.arccsc``, ``math.arccoth``, ``math.arcsech`` and ``math.arccsch`` procs.
|
||||||
- Added the procs ``math.floorMod`` and ``math.floorDiv`` for floor based integer division.
|
- Added the procs ``math.floorMod`` and ``math.floorDiv`` for floor based integer division.
|
||||||
|
- Added the procs ``rationals.`div```, ``rationals.`mod```, ``rationals.floorDiv`` and ``rationals.floorMod`` for rationals.
|
||||||
|
|
||||||
### Library changes
|
### Library changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,33 @@ proc abs*[T](x: Rational[T]): Rational[T] =
|
||||||
result.num = abs x.num
|
result.num = abs x.num
|
||||||
result.den = abs x.den
|
result.den = abs x.den
|
||||||
|
|
||||||
|
proc `div`*[T: SomeInteger](x, y: Rational[T]): T =
|
||||||
|
## Computes the rational truncated division.
|
||||||
|
(x.num * y.den) div (y.num * x.den)
|
||||||
|
|
||||||
|
proc `mod`*[T: SomeInteger](x, y: Rational[T]): Rational[T] =
|
||||||
|
## Computes the rational modulo by truncated division (remainder).
|
||||||
|
## This is same as ``x - (x div y) * y``.
|
||||||
|
result = ((x.num * y.den) mod (y.num * x.den)) // (x.den * y.den)
|
||||||
|
reduce(result)
|
||||||
|
|
||||||
|
proc floorDiv*[T: SomeInteger](x, y: Rational[T]): T =
|
||||||
|
## Computes the rational floor division.
|
||||||
|
##
|
||||||
|
## Floor division is conceptually defined as ``floor(x / y)``.
|
||||||
|
## This is different from the ``div`` operator, which is defined
|
||||||
|
## as ``trunc(x / y)``. That is, ``div`` rounds towards ``0`` and ``floorDiv``
|
||||||
|
## rounds down.
|
||||||
|
floorDiv(x.num * y.den, y.num * x.den)
|
||||||
|
|
||||||
|
proc floorMod*[T: SomeInteger](x, y: Rational[T]): Rational[T] =
|
||||||
|
## Computes the rational modulo by floor division (modulo).
|
||||||
|
##
|
||||||
|
## This is same as ``x - floorDiv(x, y) * y``.
|
||||||
|
## This proc behaves the same as the ``%`` operator in python.
|
||||||
|
result = floorMod(x.num * y.den, y.num * x.den) // (x.den * y.den)
|
||||||
|
reduce(result)
|
||||||
|
|
||||||
proc hash*[T](x: Rational[T]): Hash =
|
proc hash*[T](x: Rational[T]): Hash =
|
||||||
## Computes hash for rational `x`
|
## Computes hash for rational `x`
|
||||||
# reduce first so that hash(x) == hash(y) for x == y
|
# reduce first so that hash(x) == hash(y) for x == y
|
||||||
|
|
@ -339,3 +366,12 @@ when isMainModule:
|
||||||
assert toRational(0.33) == 33 // 100
|
assert toRational(0.33) == 33 // 100
|
||||||
assert toRational(0.22) == 11 // 50
|
assert toRational(0.22) == 11 // 50
|
||||||
assert toRational(10.0) == 10 // 1
|
assert toRational(10.0) == 10 // 1
|
||||||
|
|
||||||
|
assert (1//1) div (3//10) == 3
|
||||||
|
assert (-1//1) div (3//10) == -3
|
||||||
|
assert (3//10) mod (1//1) == 3//10
|
||||||
|
assert (-3//10) mod (1//1) == -3//10
|
||||||
|
assert floorDiv(1//1, 3//10) == 3
|
||||||
|
assert floorDiv(-1//1, 3//10) == -4
|
||||||
|
assert floorMod(3//10, 1//1) == 3//10
|
||||||
|
assert floorMod(-3//10, 1//1) == 7//10
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue