From a4628532b27857d095e69b7b162b453fc2b8373c Mon Sep 17 00:00:00 2001 From: shirleyquirk <31934565+shirleyquirk@users.noreply.github.com> Date: Fri, 15 Dec 2023 06:49:07 +0000 Subject: [PATCH] rationals: support Rational[SomeUnsignedInt] (#23046) fixes #22227 rationale: - `3u - 4u` is supported why not`3u.toRational - 4u.toRational` - all of rationals' api is on SomeInteger, looks like unsigned is declared as supported - math on unsigned rationals is meaningful and useful. --- lib/pure/rationals.nim | 12 ++++++------ tests/stdlib/trationals.nim | 9 +++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index ab05bcc252..45902b7cd4 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -40,16 +40,16 @@ func reduce*[T: SomeInteger](x: var Rational[T]) = reduce(r) doAssert r.num == 1 doAssert r.den == 2 - + if x.den == 0: + raise newException(DivByZeroDefect, "division by zero") let common = gcd(x.num, x.den) if x.den > 0: x.num = x.num div common x.den = x.den div common - elif x.den < 0: - x.num = -x.num div common - x.den = -x.den div common - else: - raise newException(DivByZeroDefect, "division by zero") + when T isnot SomeUnsignedInt: + if x.den < 0: + x.num = -x.num div common + x.den = -x.den div common func initRational*[T: SomeInteger](num, den: T): Rational[T] = ## Creates a new rational number with numerator `num` and denominator `den`. diff --git a/tests/stdlib/trationals.nim b/tests/stdlib/trationals.nim index cd9954f61d..22d7f5c2d4 100644 --- a/tests/stdlib/trationals.nim +++ b/tests/stdlib/trationals.nim @@ -10,6 +10,7 @@ template main() = z = Rational[int](num: 0, den: 1) o = initRational(num = 1, den = 1) a = initRational(1, 2) + u = 3u // 2 b = -1 // -2 m1 = -1 // 1 tt = 10 // 2 @@ -104,5 +105,13 @@ template main() = when sizeof(int) == 8: doAssert almostEqual(PI.toRational.toFloat, PI) + # unsigned + doAssert u == u + doAssert u + u == 3u // 1 + doAssert 3u.toRational - u == u + doAssert u * 2 == 3u // 1 + + + static: main() main()