#Rational

    The Rational type represents a rational number, which is a number that can be expressed as a fraction a/b where a and b are integers and b is not zero.

    #Usage

    #Arithmetic Operations

    The Rational type supports the following arithmetic operations:

    ///|
    test {
    let a = @rational.new(1L, 2L).unwrap()
    let b = @rational.new(1L, 3L).unwrap()
    assert_eq(a + b, @rational.new(5L, 6L).unwrap())
    assert_eq(a - b, @rational.new(1L, 6L).unwrap())
    assert_eq(a * b, @rational.new(1L, 6L).unwrap())
    assert_eq(a / b, @rational.new(3L, 2L).unwrap())
    assert_eq(-a, @rational.new(-1L, 2L).unwrap())
    assert_eq(a.reciprocal(), @rational.new(2L, 1L).unwrap())
    assert_eq(a.abs(), @rational.new(1L, 2L).unwrap())
    }

    #Comparison Operations

    The Rational type supports the following comparison operations:

    ///|
    test {
    let a = @rational.new(1L, 2L).unwrap()
    let b = @rational.new(1L, 3L).unwrap()
    assert_eq(a == b, false)
    assert_eq(a != b, true)
    assert_eq(a < b, false)
    assert_eq(a <= b, false)
    assert_eq(a > b, true)
    assert_eq(a >= b, true)
    assert_eq(Compare::compare(a, b), 1)
    }

    #Integer Operations

    The Rational type supports the following integer operations:

    ///|
    test {
    let a = @rational.new(1L, 2L).unwrap()
    assert_eq(a.floor(), 0)
    assert_eq(a.ceil(), 1)
    assert_eq(Show::to_string(a.fract()), "1/2")
    assert_eq(a.trunc(), 0)
    assert_eq(a.is_integer(), false)
    }

    #Double Operations

    The Rational type supports the following double operations:

    ///|
    test {
    let a = @rational.new(1L, 2L).unwrap()
    assert_eq(a.to_double(), 0.5)
    assert_eq(Show::to_string(@rational.from_double(0.5)), "1/2")
    }

    #String Operations

    The Rational type supports the following string operations:

    ///|
    test {
    let a = @rational.new(1L, 2L).unwrap()
    assert_eq(Show::to_string(a), "1/2")
    }

    BigRational

    Rational number type.

    Invariants:
    • The denominator is always positive.
    • The numerator and denominator are always coprime.

    Rational32

    type Rational32 = Rational[Int]

    Rational number type.

    Invariants:
    • The denominator is always positive.
    • The numerator and denominator are always coprime.

    Rational64

    type Rational64 = Rational[Int64]

    Rational number type.

    Invariants:
    • The denominator is always positive.
    • The numerator and denominator are always coprime.

    Integral

    trait Integral

    impl Integral for Int
    impl Integral for Int64
    impl Integral for BigInt

    RationalError

    pub(all) suberror RationalError {
    RationalError(String)
    } derive(ToJson,
    Debug
    )

    Error type for rational number operations.

    Constructor:

    • RationalError(String) : Error with a descriptive message.

    Example:

    test {
    let error = RationalError::RationalError("division by zero")
    debug_inspect(
    error,
    content=(
    #|RationalError("division by zero")
    ),
    )
    }

    impl Eq for RationalError

    RationalError::equal

    #deprecated("`RationalError::equal` is deprecated, use `Eq::equal` instead.")
    fn RationalError::equal(self : RationalError, other : RationalError) -> Bool

    RationalError::not_equal

    #deprecated("`RationalError::not_equal` is deprecated, use `Eq::not_equal` instead.")
    fn RationalError::not_equal(x : RationalError, y : RationalError) -> Bool

    RationalError::to_json

    #deprecated("`RationalError::to_json` is deprecated, use `ToJson::to_json` instead.")
    fn RationalError::to_json(RationalError) -> Json

    RationalError::to_repr

    #deprecated("`RationalError::to_repr` is deprecated, use `@moonbitlang/core/debug.Debug::to_repr` instead.")
    fn RationalError::to_repr(RationalError) ->
    Repr

    Rational

    type Rational[T] derive(Eq)

    Rational number type.

    Invariants:
    • The denominator is always positive.
    • The numerator and denominator are always coprime.
    impl Add for Rational[T]
    impl Compare for Rational[T]
    impl Div for Rational[T]
    impl Mul for Rational[T]
    impl Neg for Rational[T]
    impl Show for Rational[T]
    impl Sub for Rational[T]

    Rational::abs

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::abs(self : Rational[T]) -> Rational[T]

    Returns the absolute value of a rational number.

    Parameters:

    • self : The rational number to get the absolute value of.

    Returns a new rational number representing the absolute value of the input.

    Example:

    test {
    let positive = @rational.new(3L, 4L).unwrap()
    let negative = @rational.new(-3L, 4L).unwrap()
    inspect(positive.abs(), content="3/4")
    inspect(negative.abs(), content="3/4")
    }

    Rational::add

    #deprecated("`Rational::add` is deprecated, use `Add::add` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::add(self : Rational[T], other : Rational[T]) -> Rational[T]

    Rational::arbitrary

    #deprecated("`Rational::arbitrary` is deprecated, use `@moonbitlang/core/quickcheck.Arbitrary::arbitrary` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::arbitrary(size : Int, rs :
    RandomState
    ) -> Rational[T]

    Rational::ceil

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::ceil(self : Rational[T]) -> T

    Returns the smallest integer greater than or equal to the rational number.

    Parameters:

    • self : The rational number to ceiling.

    Returns the ceiling of the rational number as a value of type T.

    Example:

    test {
    let r1 = @rational.new(3L, 2L).unwrap() // 3/2 = 1.5
    inspect(r1.ceil(), content="2")
    let r2 = @rational.new(-3L, 2L).unwrap() // -3/2 = -1.5
    inspect(r2.ceil(), content="-1")
    let r3 = @rational.new(4L, 2L).unwrap() // 4/2 = 2.0
    inspect(r3.ceil(), content="2")
    }

    Rational::compare

    #deprecated("`Rational::compare` is deprecated, use `Compare::compare` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::compare(self : Rational[T], other : Rational[T]) -> Int

    Rational::denominator

    fn[T] Rational::denominator(self : Rational[T]) -> T

    Returns the denominator of this rational number.

    Rational::div

    #deprecated("`Rational::div` is deprecated, use `Div::div` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::div(self : Rational[T], other : Rational[T]) -> Rational[T]

    Rational::div_checked

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::div_checked(self : Rational[T], other : Rational[T]) -> Rational[T] raise RationalError

    Divides one rational number by another, raising an error when the divisor is zero.

    Parameters:

    • self : The dividend rational number.
    • other : The divisor rational number.

    Returns the quotient of the division as a rational number.

    Raises RationalError("division by zero") if other is zero.

    Example:

    test {
    let a = @rational.new(1L, 2L)
    let b = @rational.new(2L, 3L)
    match (a, b) {
    (Some(x), Some(y)) => {
    let result = x.div_checked(y)
    inspect(result, content="3/4")
    }
    _ => ()
    }
    }

    Rational::equal

    #deprecated("`Rational::equal` is deprecated, use `Eq::equal` instead.")
    fn[T : Eq] Rational::equal(Rational[T], Rational[T]) -> Bool

    Rational::floor

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::floor(self : Rational[T]) -> T

    Computes the largest integer that is less than or equal to the rational number.

    Parameters:

    • self : The rational number to floor.

    Returns the largest value of type T that is less than or equal to self.

    Example:

    test {
    let r1 = @rational.new(7L, 3L).unwrap() // 7/3 ≈ 2.33
    inspect(r1.floor(), content="2")
    let r2 = @rational.new(-7L, 3L).unwrap() // -7/3 ≈ -2.33
    inspect(r2.floor(), content="-3")
    let r3 = @rational.new(6L, 3L).unwrap() // 6/3 = 2.0
    inspect(r3.floor(), content="2")
    }

    Rational::fract

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::fract(self : Rational[T]) -> Rational[T]

    Returns the fractional part of a rational number, which is the remainder after removing the integer part.

    Parameters:

    • self : The rational number to get the fractional part from.

    Returns a new rational number representing the fractional part of self. This is equivalent to self - self.trunc().

    Example:

    test {
    let r1 = @rational.new(7L, 2L).unwrap() // 7/2 = 3.5
    inspect(r1.fract(), content="1/2") // fractional part is 0.5 = 1/2
    let r2 = @rational.new(-7L, 2L).unwrap() // -7/2 = -3.5
    inspect(r2.fract(), content="-1/2") // fractional part is -0.5 = -1/2
    let r3 = @rational.new(5L, 1L).unwrap() // 5/1 = 5
    inspect(r3.fract(), content="0") // fractional part is 0
    }

    Rational::is_integer

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::is_integer(self : Rational[T]) -> Bool

    Checks whether the rational number represents an integer value.

    Parameters:

    • self : The rational number to check.

    Returns true if the rational number is an integer (has a denominator of 1), false otherwise.

    Examples:

    test {
    let half = @rational.new(1L, 2L).unwrap()
    inspect(half.is_integer(), content="false")
    let whole = @rational.new(5L, 1L).unwrap()
    inspect(whole.is_integer(), content="true")
    let zero = @rational.new(0L, 1L).unwrap()
    inspect(zero.is_integer(), content="true")
    }

    Rational::mul

    #deprecated("`Rational::mul` is deprecated, use `Mul::mul` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::mul(self : Rational[T], other : Rational[T]) -> Rational[T]

    Rational::neg

    #deprecated("`Rational::neg` is deprecated, use `Neg::neg` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::neg(self : Rational[T]) -> Rational[T]

    Rational::not_equal

    #deprecated("`Rational::not_equal` is deprecated, use `Eq::not_equal` instead.")
    fn[T : Eq] Rational::not_equal(x : Rational[T], y : Rational[T]) -> Bool

    Rational::numerator

    fn[T] Rational::numerator(self : Rational[T]) -> T

    Returns the numerator of this rational number.

    Rational::op_ge

    #deprecated("`Rational::op_ge` is deprecated, use `Compare::op_ge` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::op_ge(x : Rational[T], y : Rational[T]) -> Bool

    Rational::op_gt

    #deprecated("`Rational::op_gt` is deprecated, use `Compare::op_gt` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::op_gt(x : Rational[T], y : Rational[T]) -> Bool

    Rational::op_le

    #deprecated("`Rational::op_le` is deprecated, use `Compare::op_le` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::op_le(x : Rational[T], y : Rational[T]) -> Bool

    Rational::op_lt

    #deprecated("`Rational::op_lt` is deprecated, use `Compare::op_lt` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::op_lt(x : Rational[T], y : Rational[T]) -> Bool

    Rational::output

    #deprecated("`Rational::output` is deprecated, use `Show::output` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::output(self : Rational[T], logger : &Logger) -> Unit

    Rational::reciprocal

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::reciprocal(self : Rational[T]) -> Rational[T]

    Returns the multiplicative inverse of a rational number.

    Parameters:

    • self : The rational number to find the reciprocal of.

    Returns a new rational number that is the reciprocal of the input.

    Example:

    test {
    let half = @rational.new(1L, 2L).unwrap()
    let two = half.reciprocal()
    inspect(two, content="2")
    let negative_third = @rational.new(-1L, 3L).unwrap()
    let negative_three = negative_third.reciprocal()
    inspect(negative_three, content="-3")
    }

    Rational::reciprocal_checked

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::reciprocal_checked(self : Rational[T]) -> Rational[T] raise RationalError

    Returns the multiplicative inverse of a rational number, raising an error when the rational number is zero.

    Parameters:

    • self : The rational number to find the reciprocal of.

    Returns a new rational number that is the reciprocal of the input.

    Raises RationalError("reciprocal of zero") if self is zero.

    Example:

    test {
    let half = @rational.new(1L, 2L).unwrap()
    let two = half.reciprocal_checked()
    inspect(two, content="2")
    }

    Rational::sub

    #deprecated("`Rational::sub` is deprecated, use `Sub::sub` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::sub(self : Rational[T], other : Rational[T]) -> Rational[T]

    Rational::to_double

    fn Rational::to_double(self : Rational[Int64]) -> Double

    Converts the rational number to its approximate double-precision floating-point representation.

    Parameters:

    • self : The rational number to convert.

    Returns the double-precision floating-point approximation of the rational number.

    Example:

    test {
    let rational = @rational.new(1L, 2L).unwrap()
    inspect(rational.to_double(), content="0.5")
    let negative = @rational.new(-3L, 4L).unwrap()
    inspect(negative.to_double(), content="-0.75")
    }

    Rational::to_repr

    #deprecated("`Rational::to_repr` is deprecated, use `@moonbitlang/core/debug.Debug::to_repr` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::to_repr(self : Rational[T]) ->
    Repr

    Rational::to_string

    #deprecated("`Rational::to_string` is deprecated, use `Show::to_string` instead.")
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::to_string(self : Rational[T]) -> String

    Rational::trunc

    #as_free_fn
    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] Rational::trunc(self : Rational[T]) -> T

    Truncates a rational number towards zero, returning the integer part.

    Parameters:

    • self : The rational number to truncate.

    Returns the integer part of the rational number as a value of type T.

    Example:

    test {
    let a = @rational.new(7L, 3L).unwrap() // 7/3 = 2.333...
    inspect(a.trunc(), content="2")
    let b = @rational.new(-7L, 3L).unwrap() // -7/3 = -2.333...
    inspect(b.trunc(), content="-2")
    let c = @rational.new(5L, 2L).unwrap() // 5/2 = 2.5
    inspect(c.trunc(), content="2")
    let d = @rational.new(-5L, 2L).unwrap() // -5/2 = -2.5
    inspect(d.trunc(), content="-2")
    }

    from_double

    fn from_double(value : Double) -> Rational[Int64] raise RationalError

    Converts a floating-point number to its rational representation using a continued fraction algorithm.

    Parameters:

    • value : The double-precision floating-point number to convert to a rational.

    Returns a rational number that approximates the input value.

    Throws an error of type RationalError if the input is NaN or if the conversion would result in integer overflow.

    Example:

    test {
    // Convert 0.5 to rational 1/2
    let half = @rational.from_double(0.5)
    inspect(half, content="1/2")

    // Convert 0.333... to a close rational approximation
    let third = @rational.from_double(1.0 / 3.0)
    inspect(third, content="1/3")
    }

    new

    fn[T : Integral + Add + Sub + Mul + Div + Neg + Mod + Show + Eq + Compare +
    Arbitrary
    ] new(numerator : T, denominator : T) -> Rational[T]?

    Creates a rational number from the given numerator and denominator.

    Parameters:

    • numerator : The numerator of the rational number.
    • denominator : The denominator of the rational number.

    Returns Some(rational) if the denominator is non-zero and the reduced form fits in T, where the rational number is automatically reduced to its simplest form with a positive denominator. Returns None if the denominator is zero, or if the reduced form cannot be represented in T (e.g. its denominator is 2^63 for Rational[Int64]).

    Example:

    test {
    // Create 3/4
    let r1 = @rational.new(3L, 4L).unwrap()
    inspect(r1, content="3/4")

    // Create -1/2 (negative numerator)
    let r2 = @rational.new(-1L, 2L).unwrap()
    inspect(r2, content="-1/2")

    // Create -1/2 (negative denominator gets normalized)
    let r3 = @rational.new(1L, -2L).unwrap()
    inspect(r3, content="-1/2")

    // Create 1/2 (double negatives cancel out)
    let r4 = @rational.new(-1L, -2L).unwrap()
    inspect(r4, content="1/2")

    // Automatic reduction to simplest form
    let r5 = @rational.new(6L, 9L).unwrap()
    inspect(r5, content="2/3")

    // Division by zero returns None
    let r6 = @rational.new(1L, 0L)
    assert_true(r6 is None)
    }