rationals.nim: Use func everywhere (#16302)
This commit is contained in:
parent
17a835a7b2
commit
87e634aab3
2 changed files with 42 additions and 41 deletions
|
|
@ -18,28 +18,28 @@ type Rational*[T] = object
|
||||||
## a rational number, consisting of a numerator and denominator
|
## a rational number, consisting of a numerator and denominator
|
||||||
num*, den*: T
|
num*, den*: T
|
||||||
|
|
||||||
proc initRational*[T: SomeInteger](num, den: T): Rational[T] =
|
func initRational*[T: SomeInteger](num, den: T): Rational[T] =
|
||||||
## Create a new rational number.
|
## Create a new rational number.
|
||||||
assert(den != 0, "a denominator of zero value is invalid")
|
assert(den != 0, "a denominator of zero value is invalid")
|
||||||
result.num = num
|
result.num = num
|
||||||
result.den = den
|
result.den = den
|
||||||
|
|
||||||
proc `//`*[T](num, den: T): Rational[T] = initRational[T](num, den)
|
func `//`*[T](num, den: T): Rational[T] = initRational[T](num, den)
|
||||||
## A friendlier version of `initRational`. Example usage:
|
## A friendlier version of `initRational`. Example usage:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## var x = 1//3 + 1//5
|
## var x = 1//3 + 1//5
|
||||||
|
|
||||||
proc `$`*[T](x: Rational[T]): string =
|
func `$`*[T](x: Rational[T]): string =
|
||||||
## Turn a rational number into a string.
|
## Turn a rational number into a string.
|
||||||
result = $x.num & "/" & $x.den
|
result = $x.num & "/" & $x.den
|
||||||
|
|
||||||
proc toRational*[T: SomeInteger](x: T): Rational[T] =
|
func toRational*[T: SomeInteger](x: T): Rational[T] =
|
||||||
## Convert some integer `x` to a rational number.
|
## Convert some integer `x` to a rational number.
|
||||||
result.num = x
|
result.num = x
|
||||||
result.den = 1
|
result.den = 1
|
||||||
|
|
||||||
proc toRational*(x: float,
|
func toRational*(x: float,
|
||||||
n: int = high(int) shr (sizeof(int) div 2 * 8)): Rational[int] =
|
n: int = high(int) shr (sizeof(int) div 2 * 8)): Rational[int] =
|
||||||
## Calculates the best rational numerator and denominator
|
## Calculates the best rational numerator and denominator
|
||||||
## that approximates to `x`, where the denominator is
|
## that approximates to `x`, where the denominator is
|
||||||
|
|
@ -74,16 +74,16 @@ proc toRational*(x: float,
|
||||||
ai = int(x)
|
ai = int(x)
|
||||||
result = m11 // m21
|
result = m11 // m21
|
||||||
|
|
||||||
proc toFloat*[T](x: Rational[T]): float =
|
func toFloat*[T](x: Rational[T]): float =
|
||||||
## Convert a rational number `x` to a float.
|
## Convert a rational number `x` to a float.
|
||||||
x.num / x.den
|
x.num / x.den
|
||||||
|
|
||||||
proc toInt*[T](x: Rational[T]): int =
|
func toInt*[T](x: Rational[T]): int =
|
||||||
## Convert a rational number `x` to an int. Conversion rounds towards 0 if
|
## Convert a rational number `x` to an int. Conversion rounds towards 0 if
|
||||||
## `x` does not contain an integer value.
|
## `x` does not contain an integer value.
|
||||||
x.num div x.den
|
x.num div x.den
|
||||||
|
|
||||||
proc reduce*[T: SomeInteger](x: var Rational[T]) =
|
func reduce*[T: SomeInteger](x: var Rational[T]) =
|
||||||
## Reduce rational `x`.
|
## Reduce rational `x`.
|
||||||
let common = gcd(x.num, x.den)
|
let common = gcd(x.num, x.den)
|
||||||
if x.den > 0:
|
if x.den > 0:
|
||||||
|
|
@ -95,97 +95,97 @@ proc reduce*[T: SomeInteger](x: var Rational[T]) =
|
||||||
else:
|
else:
|
||||||
raise newException(DivByZeroDefect, "division by zero")
|
raise newException(DivByZeroDefect, "division by zero")
|
||||||
|
|
||||||
proc `+` *[T](x, y: Rational[T]): Rational[T] =
|
func `+` *[T](x, y: Rational[T]): Rational[T] =
|
||||||
## Add two rational numbers.
|
## Add two rational numbers.
|
||||||
let common = lcm(x.den, y.den)
|
let common = lcm(x.den, y.den)
|
||||||
result.num = common div x.den * x.num + common div y.den * y.num
|
result.num = common div x.den * x.num + common div y.den * y.num
|
||||||
result.den = common
|
result.den = common
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `+` *[T](x: Rational[T], y: T): Rational[T] =
|
func `+` *[T](x: Rational[T], y: T): Rational[T] =
|
||||||
## Add rational `x` to int `y`.
|
## Add rational `x` to int `y`.
|
||||||
result.num = x.num + y * x.den
|
result.num = x.num + y * x.den
|
||||||
result.den = x.den
|
result.den = x.den
|
||||||
|
|
||||||
proc `+` *[T](x: T, y: Rational[T]): Rational[T] =
|
func `+` *[T](x: T, y: Rational[T]): Rational[T] =
|
||||||
## Add int `x` to rational `y`.
|
## Add int `x` to rational `y`.
|
||||||
result.num = x * y.den + y.num
|
result.num = x * y.den + y.num
|
||||||
result.den = y.den
|
result.den = y.den
|
||||||
|
|
||||||
proc `+=` *[T](x: var Rational[T], y: Rational[T]) =
|
func `+=` *[T](x: var Rational[T], y: Rational[T]) =
|
||||||
## Add rational `y` to rational `x`.
|
## Add rational `y` to rational `x`.
|
||||||
let common = lcm(x.den, y.den)
|
let common = lcm(x.den, y.den)
|
||||||
x.num = common div x.den * x.num + common div y.den * y.num
|
x.num = common div x.den * x.num + common div y.den * y.num
|
||||||
x.den = common
|
x.den = common
|
||||||
reduce(x)
|
reduce(x)
|
||||||
|
|
||||||
proc `+=` *[T](x: var Rational[T], y: T) =
|
func `+=` *[T](x: var Rational[T], y: T) =
|
||||||
## Add int `y` to rational `x`.
|
## Add int `y` to rational `x`.
|
||||||
x.num += y * x.den
|
x.num += y * x.den
|
||||||
|
|
||||||
proc `-` *[T](x: Rational[T]): Rational[T] =
|
func `-` *[T](x: Rational[T]): Rational[T] =
|
||||||
## Unary minus for rational numbers.
|
## Unary minus for rational numbers.
|
||||||
result.num = -x.num
|
result.num = -x.num
|
||||||
result.den = x.den
|
result.den = x.den
|
||||||
|
|
||||||
proc `-` *[T](x, y: Rational[T]): Rational[T] =
|
func `-` *[T](x, y: Rational[T]): Rational[T] =
|
||||||
## Subtract two rational numbers.
|
## Subtract two rational numbers.
|
||||||
let common = lcm(x.den, y.den)
|
let common = lcm(x.den, y.den)
|
||||||
result.num = common div x.den * x.num - common div y.den * y.num
|
result.num = common div x.den * x.num - common div y.den * y.num
|
||||||
result.den = common
|
result.den = common
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `-` *[T](x: Rational[T], y: T): Rational[T] =
|
func `-` *[T](x: Rational[T], y: T): Rational[T] =
|
||||||
## Subtract int `y` from rational `x`.
|
## Subtract int `y` from rational `x`.
|
||||||
result.num = x.num - y * x.den
|
result.num = x.num - y * x.den
|
||||||
result.den = x.den
|
result.den = x.den
|
||||||
|
|
||||||
proc `-` *[T](x: T, y: Rational[T]): Rational[T] =
|
func `-` *[T](x: T, y: Rational[T]): Rational[T] =
|
||||||
## Subtract rational `y` from int `x`.
|
## Subtract rational `y` from int `x`.
|
||||||
result.num = x * y.den - y.num
|
result.num = x * y.den - y.num
|
||||||
result.den = y.den
|
result.den = y.den
|
||||||
|
|
||||||
proc `-=` *[T](x: var Rational[T], y: Rational[T]) =
|
func `-=` *[T](x: var Rational[T], y: Rational[T]) =
|
||||||
## Subtract rational `y` from rational `x`.
|
## Subtract rational `y` from rational `x`.
|
||||||
let common = lcm(x.den, y.den)
|
let common = lcm(x.den, y.den)
|
||||||
x.num = common div x.den * x.num - common div y.den * y.num
|
x.num = common div x.den * x.num - common div y.den * y.num
|
||||||
x.den = common
|
x.den = common
|
||||||
reduce(x)
|
reduce(x)
|
||||||
|
|
||||||
proc `-=` *[T](x: var Rational[T], y: T) =
|
func `-=` *[T](x: var Rational[T], y: T) =
|
||||||
## Subtract int `y` from rational `x`.
|
## Subtract int `y` from rational `x`.
|
||||||
x.num -= y * x.den
|
x.num -= y * x.den
|
||||||
|
|
||||||
proc `*` *[T](x, y: Rational[T]): Rational[T] =
|
func `*` *[T](x, y: Rational[T]): Rational[T] =
|
||||||
## Multiply two rational numbers.
|
## Multiply two rational numbers.
|
||||||
result.num = x.num * y.num
|
result.num = x.num * y.num
|
||||||
result.den = x.den * y.den
|
result.den = x.den * y.den
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `*` *[T](x: Rational[T], y: T): Rational[T] =
|
func `*` *[T](x: Rational[T], y: T): Rational[T] =
|
||||||
## Multiply rational `x` with int `y`.
|
## Multiply rational `x` with int `y`.
|
||||||
result.num = x.num * y
|
result.num = x.num * y
|
||||||
result.den = x.den
|
result.den = x.den
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `*` *[T](x: T, y: Rational[T]): Rational[T] =
|
func `*` *[T](x: T, y: Rational[T]): Rational[T] =
|
||||||
## Multiply int `x` with rational `y`.
|
## Multiply int `x` with rational `y`.
|
||||||
result.num = x * y.num
|
result.num = x * y.num
|
||||||
result.den = y.den
|
result.den = y.den
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `*=` *[T](x: var Rational[T], y: Rational[T]) =
|
func `*=` *[T](x: var Rational[T], y: Rational[T]) =
|
||||||
## Multiply rationals `y` to `x`.
|
## Multiply rationals `y` to `x`.
|
||||||
x.num *= y.num
|
x.num *= y.num
|
||||||
x.den *= y.den
|
x.den *= y.den
|
||||||
reduce(x)
|
reduce(x)
|
||||||
|
|
||||||
proc `*=` *[T](x: var Rational[T], y: T) =
|
func `*=` *[T](x: var Rational[T], y: T) =
|
||||||
## Multiply int `y` to rational `x`.
|
## Multiply int `y` to rational `x`.
|
||||||
x.num *= y
|
x.num *= y
|
||||||
reduce(x)
|
reduce(x)
|
||||||
|
|
||||||
proc reciprocal*[T](x: Rational[T]): Rational[T] =
|
func reciprocal*[T](x: Rational[T]): Rational[T] =
|
||||||
## Calculate the reciprocal of `x`. (1/x)
|
## Calculate the reciprocal of `x`. (1/x)
|
||||||
if x.num > 0:
|
if x.num > 0:
|
||||||
result.num = x.den
|
result.num = x.den
|
||||||
|
|
@ -196,63 +196,63 @@ proc reciprocal*[T](x: Rational[T]): Rational[T] =
|
||||||
else:
|
else:
|
||||||
raise newException(DivByZeroDefect, "division by zero")
|
raise newException(DivByZeroDefect, "division by zero")
|
||||||
|
|
||||||
proc `/`*[T](x, y: Rational[T]): Rational[T] =
|
func `/`*[T](x, y: Rational[T]): Rational[T] =
|
||||||
## Divide rationals `x` by `y`.
|
## Divide rationals `x` by `y`.
|
||||||
result.num = x.num * y.den
|
result.num = x.num * y.den
|
||||||
result.den = x.den * y.num
|
result.den = x.den * y.num
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `/`*[T](x: Rational[T], y: T): Rational[T] =
|
func `/`*[T](x: Rational[T], y: T): Rational[T] =
|
||||||
## Divide rational `x` by int `y`.
|
## Divide rational `x` by int `y`.
|
||||||
result.num = x.num
|
result.num = x.num
|
||||||
result.den = x.den * y
|
result.den = x.den * y
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `/`*[T](x: T, y: Rational[T]): Rational[T] =
|
func `/`*[T](x: T, y: Rational[T]): Rational[T] =
|
||||||
## Divide int `x` by Rational `y`.
|
## Divide int `x` by Rational `y`.
|
||||||
result.num = x * y.den
|
result.num = x * y.den
|
||||||
result.den = y.num
|
result.den = y.num
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc `/=`*[T](x: var Rational[T], y: Rational[T]) =
|
func `/=`*[T](x: var Rational[T], y: Rational[T]) =
|
||||||
## Divide rationals `x` by `y` in place.
|
## Divide rationals `x` by `y` in place.
|
||||||
x.num *= y.den
|
x.num *= y.den
|
||||||
x.den *= y.num
|
x.den *= y.num
|
||||||
reduce(x)
|
reduce(x)
|
||||||
|
|
||||||
proc `/=`*[T](x: var Rational[T], y: T) =
|
func `/=`*[T](x: var Rational[T], y: T) =
|
||||||
## Divide rational `x` by int `y` in place.
|
## Divide rational `x` by int `y` in place.
|
||||||
x.den *= y
|
x.den *= y
|
||||||
reduce(x)
|
reduce(x)
|
||||||
|
|
||||||
proc cmp*(x, y: Rational): int =
|
func cmp*(x, y: Rational): int =
|
||||||
## Compares two rationals.
|
## Compares two rationals.
|
||||||
(x - y).num
|
(x - y).num
|
||||||
|
|
||||||
proc `<` *(x, y: Rational): bool =
|
func `<` *(x, y: Rational): bool =
|
||||||
(x - y).num < 0
|
(x - y).num < 0
|
||||||
|
|
||||||
proc `<=` *(x, y: Rational): bool =
|
func `<=` *(x, y: Rational): bool =
|
||||||
(x - y).num <= 0
|
(x - y).num <= 0
|
||||||
|
|
||||||
proc `==` *(x, y: Rational): bool =
|
func `==` *(x, y: Rational): bool =
|
||||||
(x - y).num == 0
|
(x - y).num == 0
|
||||||
|
|
||||||
proc abs*[T](x: Rational[T]): Rational[T] =
|
func 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 =
|
func `div`*[T: SomeInteger](x, y: Rational[T]): T =
|
||||||
## Computes the rational truncated division.
|
## Computes the rational truncated division.
|
||||||
(x.num * y.den) div (y.num * x.den)
|
(x.num * y.den) div (y.num * x.den)
|
||||||
|
|
||||||
proc `mod`*[T: SomeInteger](x, y: Rational[T]): Rational[T] =
|
func `mod`*[T: SomeInteger](x, y: Rational[T]): Rational[T] =
|
||||||
## Computes the rational modulo by truncated division (remainder).
|
## Computes the rational modulo by truncated division (remainder).
|
||||||
## This is same as ``x - (x div y) * y``.
|
## This is same as ``x - (x div y) * y``.
|
||||||
result = ((x.num * y.den) mod (y.num * x.den)) // (x.den * y.den)
|
result = ((x.num * y.den) mod (y.num * x.den)) // (x.den * y.den)
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc floorDiv*[T: SomeInteger](x, y: Rational[T]): T =
|
func floorDiv*[T: SomeInteger](x, y: Rational[T]): T =
|
||||||
## Computes the rational floor division.
|
## Computes the rational floor division.
|
||||||
##
|
##
|
||||||
## Floor division is conceptually defined as ``floor(x / y)``.
|
## Floor division is conceptually defined as ``floor(x / y)``.
|
||||||
|
|
@ -261,15 +261,15 @@ proc floorDiv*[T: SomeInteger](x, y: Rational[T]): T =
|
||||||
## rounds down.
|
## rounds down.
|
||||||
floorDiv(x.num * y.den, y.num * x.den)
|
floorDiv(x.num * y.den, y.num * x.den)
|
||||||
|
|
||||||
proc floorMod*[T: SomeInteger](x, y: Rational[T]): Rational[T] =
|
func floorMod*[T: SomeInteger](x, y: Rational[T]): Rational[T] =
|
||||||
## Computes the rational modulo by floor division (modulo).
|
## Computes the rational modulo by floor division (modulo).
|
||||||
##
|
##
|
||||||
## This is same as ``x - floorDiv(x, y) * y``.
|
## This is same as ``x - floorDiv(x, y) * y``.
|
||||||
## This proc behaves the same as the ``%`` operator in python.
|
## This func behaves the same as the ``%`` operator in python.
|
||||||
result = floorMod(x.num * y.den, y.num * x.den) // (x.den * y.den)
|
result = floorMod(x.num * y.den, y.num * x.den) // (x.den * y.den)
|
||||||
reduce(result)
|
reduce(result)
|
||||||
|
|
||||||
proc hash*[T](x: Rational[T]): Hash =
|
func 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
|
||||||
var copy = x
|
var copy = x
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import
|
||||||
httpcore,
|
httpcore,
|
||||||
math,
|
math,
|
||||||
nre,
|
nre,
|
||||||
|
rationals,
|
||||||
sequtils,
|
sequtils,
|
||||||
strutils,
|
strutils,
|
||||||
uri
|
uri
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue