An arbitrary-precision rational number.

Memory is allocated as needed for operations to ensure full precision is kept. The precision of a Rational is only bounded by memory.

Rational’s are always normalized. That is, for a Rational r = p/q where p and q are integers, gcd(p, q) = 1 always.

TODO rework this to store its own allocator and use a non-managed big int, to avoid double allocator storage.

Fields

p: Int,

Numerator. Determines the sign of the Rational.

q: Int,

Denominator. Sign is ignored.

Functions

fn abs(r: *Rational) void

Make a Rational positive.

fn add(rma: *Rational, a: Rational, b: Rational) !void

rma = a + b.

rma = a + b.

rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.

Returns an error if memory could not be allocated.

fn copyInt(self: *Rational, a: Int) !void

Set a Rational directly from an Int.

fn copyRatio(self: *Rational, a: Int, b: Int) !void

Set a Rational directly from a ratio of two Int’s.

fn deinit(self: *Rational) void

Frees all memory associated with a Rational.

fn div(r: *Rational, a: Rational, b: Rational) !void

rma = a / b.

rma = a / b.

rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.

Returns an error if memory could not be allocated.

fn init(a: Allocator) !Rational

Create a new Rational. A small amount of memory will be allocated on initializat…

Create a new Rational. A small amount of memory will be allocated on initialization. This will be 2 * Int.default_capacity.

fn invert(r: *Rational) void

Invert the numerator and denominator fields of a Rational. p/q => q/p.

fn mul(r: *Rational, a: Rational, b: Rational) !void

rma = a * b.

rma = a * b.

rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.

Returns an error if memory could not be allocated.

fn negate(r: *Rational) void

Negate the sign of a Rational.

fn order(a: Rational, b: Rational) !math.Order

Returns math.Order.lt, math.Order.eq, math.Order.gt if a < b, a == b or a

b r…

Returns math.Order.lt, math.Order.eq, math.Order.gt if a < b, a == b or a

b respectively.

fn orderAbs(a: Rational, b: Rational) !math.Order

Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| == |b| or…

Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| == |b| or |a| > |b| respectively.

fn setFloat(self: *Rational, comptime T: type, f: T) !void

Set a Rational from a floating-point value. The rational will have enough precis…

Set a Rational from a floating-point value. The rational will have enough precision to completely represent the provided float.

fn setFloatString(self: *Rational, str: []const u8) !void

Set a Rational from a string of the form A/B where A and B are base-10 integer…

Set a Rational from a string of the form A/B where A and B are base-10 integers.

fn setInt(self: *Rational, a: anytype) !void

Set a Rational from a primitive integer type.

fn setRatio(self: *Rational, p: anytype, q: anytype) !void

Set a rational from an integer ratio.

fn sub(rma: *Rational, a: Rational, b: Rational) !void

rma = a - b.

rma = a - b.

rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.

Returns an error if memory could not be allocated.

fn swap(r: *Rational, other: *Rational) void

Efficiently swap a Rational with another. This swaps the limb pointers and a ful…

Efficiently swap a Rational with another. This swaps the limb pointers and a full copy is not performed. The address of the limbs field will not be the same after this function.

fn toFloat(self: Rational, comptime T: type) !T

Return a floating-point value that is the closest value to a Rational.

Return a floating-point value that is the closest value to a Rational.

The result may not be exact if the Rational is too precise or too large for the target type.