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.
This commit is contained in:
shirleyquirk
2023-12-15 06:49:07 +00:00
committed by GitHub
parent 94f7e9683f
commit a4628532b2
2 changed files with 15 additions and 6 deletions

View File

@@ -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`.

View File

@@ -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()