diff options
author | Koki Fushimi <paalon1936@gmail.com> | 2018-06-02 00:19:25 +0900 |
---|---|---|
committer | Varriount <Varriount@users.noreply.github.com> | 2018-06-01 11:19:25 -0400 |
commit | 3027ca292c3fbdb5387d0b8834c7e3dc960df75d (patch) | |
tree | ebc28d12e9bfe76e573d308ee7a22411c7c963cd | |
parent | 829f89d6491302072ec1b1153d34dc07361f9fbb (diff) | |
download | Nim-3027ca292c3fbdb5387d0b8834c7e3dc960df75d.tar.gz |
Support `div`, `mod`, floorDiv and floorMod for Rationals (#7918)
* Support `div`, `mod`, floorDiv and floorMod for Ratinoals. * Bug fix and add tests. * Update changelog
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | lib/pure/rationals.nim | 36 |
2 files changed, 37 insertions, 0 deletions
diff --git a/changelog.md b/changelog.md index 2bbfd01f6..514bfbaca 100644 --- a/changelog.md +++ b/changelog.md @@ -64,6 +64,7 @@ - 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 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 diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index 7907b4e6c..3946cf85b 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -241,6 +241,33 @@ proc abs*[T](x: Rational[T]): Rational[T] = result.num = abs x.num 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 = ## Computes hash for rational `x` # 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.22) == 11 // 50 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 |