bend-kit-bignum Releases (1): 0.1.0.0 0xbf5d8bf07d7411858acb5142889fc4d7 indexed https://jend.leeeet.dev/files.txt?path=bend-kit-bignum@0.1.0.0 Definitions (136, 1 to 100 shown): Bigint.BigInt (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt) # A magnitude is a list of base-10^4 limbs in U32, least significant first, # with no zero limb on top. Base 10^4 keeps every limb product and its carries # below 2^32, and makes decimal show and read linear. Zero is never negative. type BigInt is Data: BigInt{neg: Bool, mag: List<&2, U32>} Bigint.Mag.if (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.if) # A match cannot scrutinize a computed Bool, so each branch is a closure. def Mag.if(-A: Type, c: Bool, t: Unit -> A, e: Unit -> A) -> A: Bigint.Mag.lone (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.lone) def Mag.lone(z: Bool, x: U32) -> List<&2, U32>: Bigint.Mag.cons (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.cons) # x + r * 10^4, dropping a zero limb on top. def Mag.cons(+x: U32, r: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.norm (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.norm) def Mag.norm(xs: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.len (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.len) def Mag.len(xs: List<&2, U32>) -> Nat: Bigint.Mag.at (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.at) def Mag.at(xs: List<&2, U32>, i: Nat) -> U32: Bigint.Mag.top (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.top) def Mag.top(xs: List<&2, U32>) -> U32: Bigint.Mag.odd (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.odd) def Mag.odd(xs: List<&2, U32>) -> Bool: Bigint.Mag.inc (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.inc) # The limbs are 0 or 1 in z: z says the carry c is 0, so a stays as is. def Mag.inc(a: List<&2, U32>, z: Bool, +c: U32) -> List<&2, U32>: Bigint.Mag.add (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.add) def Mag.add(a: List<&2, U32>, b: List<&2, U32>, +c: U32) -> List<&2, U32>: Bigint.Mag.dec (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.dec) # a - w for the borrow w; z says w is 0. Leaves zero limbs on top. def Mag.dec(a: List<&2, U32>, z: Bool, +w: U32) -> List<&2, U32>: Bigint.Mag.sub (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.sub) # a - b - w for a >= b + w. Leaves zero limbs on top: callers norm. def Mag.sub(a: List<&2, U32>, b: List<&2, U32>, +w: U32) -> List<&2, U32>: Bigint.Mag.then (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.then) def Mag.then(hi: Cmp, lo: Cmp) -> Cmp: Bigint.Mag.cmp (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.cmp) # Both canonical, so the longer one is larger. def Mag.cmp(a: List<&2, U32>, b: List<&2, U32>) -> Cmp: Bigint.Mag.mul1 (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.mul1) # a * m + c for m, c below 10^4. def Mag.mul1(a: List<&2, U32>, +m: U32, +c: U32) -> List<&2, U32>: Bigint.Mag.scale (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.scale) def Mag.scale(+a: List<&2, U32>, +m: U32) -> List<&2, U32>: Bigint.Mag.school.put (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.school.put) def Mag.school.put(p: List<&2, U32>, r: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.school (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.school) def Mag.school(a: List<&2, U32>, +b: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.zeros (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.zeros) def Mag.zeros(n: Nat, xs: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.shift (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.shift) # xs * 10^(4 n). def Mag.shift(xs: List<&2, U32>, n: Nat) -> List<&2, U32>: Bigint.Mag.lo (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.lo) def Mag.lo(xs: List<&2, U32>, k: Nat) -> List<&2, U32>: Bigint.Mag.kara (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.kara) # z0 + (s - z0 - z2) B^k + z2 B^2k, with B = 10^(4 k). def Mag.kara(+k: Nat, +z0: List<&2, U32>, +z2: List<&2, U32>, s: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.kmul (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.kmul) # Karatsuba while both sides have at least 32 limbs, schoolbook below. f caps # the depth; 32 halvings outrun any list that fits in memory. def Mag.kmul(+f: Nat, +a: List<&2, U32>, +b: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.mul (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.mul) def Mag.mul(a: List<&2, U32>, b: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.dsmall (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.dsmall) # Short division of a big-endian list by d below 10^4 with remainder rem: # the quotient comes out little-endian, with zero limbs on top. def Mag.dsmall(xs: List<&2, U32>, +d: U32, +rem: U32, acc: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.half (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.half) def Mag.half(+xs: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.fix (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.fix) # Knuth's Algorithm D step D6: the estimate d is at most 2 over the true # quotient digit, so f = 3 steps of p - bn always settle it. def Mag.fix(+f: Nat, +d: U32, +p: List<&2, U32>, +r: List<&2, U32>, +bn: List<&2, U32>, +q: List<&2, U32>) -> List<&2, U32> & List<&2, U32>: Bigint.Mag.step (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.step) # One quotient digit: bring limb x down into r, estimate from r's top two # limbs over bn's top limb vt, and correct. def Mag.step(x: U32, +bn: List<&2, U32>, +n: Nat, +n1: Nat, +vt: U32, qr: List<&2, U32> & List<&2, U32>) -> List<&2, U32> & List<&2, U32>: Bigint.Mag.long (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.long) # Long division over the dividend's limbs, most significant first. Quotient # digits are consed, so the quotient comes out little-endian. def Mag.long(xs: List<&2, U32>, +bn: List<&2, U32>, +n: Nat, +n1: Nat, +vt: U32, qr: List<&2, U32> & List<&2, U32>) -> List<&2, U32> & List<&2, U32>: Bigint.Mag.divmod.fin (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.divmod.fin) def Mag.divmod.fin(+f: U32, qr: List<&2, U32> & List<&2, U32>) -> List<&2, U32> & List<&2, U32>: Bigint.Mag.divmod (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.divmod) # a / b and a % b for b above 0. Both scale by f so that b's top limb is at # least 10^4 / 2 (Knuth D1), and the remainder scales back. def Mag.divmod(a: List<&2, U32>, +b: List<&2, U32>) -> List<&2, U32> & List<&2, U32>: Bigint.Mag.snd (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.snd) def Mag.snd(qr: List<&2, U32> & List<&2, U32>) -> List<&2, U32>: Bigint.Mag.rem (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.rem) def Mag.rem(a: List<&2, U32>, b: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.pow (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.pow) # b^e * acc by squaring; e <= f, and e halves as f counts down. def Mag.pow(+f: Nat, +b: List<&2, U32>, +e: Nat, +acc: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.modpow (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.modpow) # b^e * acc mod m, with b and acc below m. f counts e's bits: 14 per limb, # since 10^4 < 2^14. def Mag.modpow(+f: Nat, +b: List<&2, U32>, +e: List<&2, U32>, +acc: List<&2, U32>, +m: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.gcd (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.gcd) # Euclid. Lame: under 5 steps per decimal digit of the smaller, so f from # 20 per limb of both never runs out. def Mag.gcd(+f: Nat, +a: List<&2, U32>, +b: List<&2, U32>) -> List<&2, U32>: Bigint.Mag.dig (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.dig) def Mag.dig(d: U32) -> Char: Bigint.Mag.d4 (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.d4) def Mag.d4(+x: U32, acc: String) -> String: Bigint.Mag.show (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.show) # The top limb unpadded, every lower limb as four digits. def Mag.show(xs: List<&2, U32>, acc: String) -> String: Bigint.Mag.digits (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.digits) # The digit values of s, last first, and whether every char was a digit. def Mag.digits(s: String, ok: Bool, acc: List<&2, U32>) -> Bool & List<&2, U32>: Bigint.Mag.group (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.group) # Digits, least significant first, four to a limb. def Mag.group(ds: List<&2, U32>) -> List<&2, U32>: Bigint.BigInt.mk (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.mk) def BigInt.mk(neg: Bool, m: List<&2, U32>) -> BigInt: Bigint.BigInt.zero (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.zero) def BigInt.zero() -> BigInt: Bigint.BigInt.one (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.one) def BigInt.one() -> BigInt: Bigint.BigInt.from_u32 (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.from_u32) def BigInt.from_u32(+x: U32) -> BigInt: Bigint.BigInt.neg (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.neg) def BigInt.neg(x: BigInt) -> BigInt: Bigint.BigInt.abs (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.abs) def BigInt.abs(x: BigInt) -> BigInt: Bigint.BigInt.is_zero (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.is_zero) def BigInt.is_zero(x: BigInt) -> Bool: Bigint.BigInt.cmp (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.cmp) def BigInt.cmp(a: BigInt, b: BigInt) -> Cmp: Bigint.BigInt.add.mixed (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.add.mixed) # Signs differ: the larger magnitude keeps its sign. def BigInt.add.mixed(c: Cmp, +sa: Bool, x: List<&2, U32>, y: List<&2, U32>) -> BigInt: Bigint.BigInt.add.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.add.go) def BigInt.add.go(diff: Bool, sa: Bool, +x: List<&2, U32>, +y: List<&2, U32>) -> BigInt: Bigint.BigInt.add (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.add) def BigInt.add(a: BigInt, b: BigInt) -> BigInt: Bigint.BigInt.sub (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.sub) def BigInt.sub(a: BigInt, b: BigInt) -> BigInt: Bigint.BigInt.mul (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.mul) def BigInt.mul(a: BigInt, b: BigInt) -> BigInt: Bigint.BigInt.divmod.fin (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.divmod.fin) def BigInt.divmod.fin(+sa: Bool, sb: Bool, qr: List<&2, U32> & List<&2, U32>) -> BigInt & BigInt: Bigint.BigInt.divmod (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.divmod) # Truncates toward zero: the remainder takes the dividend's sign. def BigInt.divmod(a: BigInt, b: BigInt) -> Maybe<&1, BigInt & BigInt>: Bigint.BigInt.pow (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.pow) def BigInt.pow(b: BigInt, +e: Nat) -> BigInt: Bigint.Mag.base (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=Mag.base) # The base's residue in [0, m). def Mag.base(neg: Bool, +r: List<&2, U32>, +m: List<&2, U32>) -> List<&2, U32>: Bigint.BigInt.modpow.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.modpow.go) def BigInt.modpow.go(neg_e: Bool, sb: Bool, x: List<&2, U32>, +y: List<&2, U32>, +m: List<&2, U32>) -> Maybe<&2, BigInt>: Bigint.BigInt.modpow (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.modpow) # b^e mod |m| in [0, |m|). None for m = 0 or e < 0. def BigInt.modpow(b: BigInt, e: BigInt, m: BigInt) -> Maybe<&2, BigInt>: Bigint.BigInt.gcd (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.gcd) # Never negative; gcd(0, 0) is 0. def BigInt.gcd(a: BigInt, b: BigInt) -> BigInt: Bigint.BigInt.show (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.show) def BigInt.show(x: BigInt) -> String: Bigint.BigInt.read.fin (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.read.fin) def BigInt.read.fin(neg: Bool, r: Bool & List<&2, U32>) -> Maybe<&2, BigInt>: Bigint.BigInt.read (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/bigint.bend&name=BigInt.read) # An optional '-' and at least one ASCII digit; leading zeros are fine. def BigInt.read(s: String) -> Maybe<&2, BigInt>: Decimal.Decimal (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal) # The value is unscaled / 10^scale. Scale is kept as written, so 1.50 stays # 1.50 (money keeps its cents); cmp is numeric, and normalize strips trailing # zeros. No operation rounds: an inexact request answers None. type Decimal is Data: Decimal{unscaled: Big.BigInt, scale: Nat} Decimal.Decimal.zero (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.zero) def Decimal.zero() -> Decimal: Decimal.Decimal.pow10 (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.pow10) def Decimal.pow10(n: Nat) -> Big.BigInt: Decimal.Decimal.up (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.up) # u * 10^k, without a multiply when k is 0. def Decimal.up(u: Big.BigInt, k: Nat) -> Big.BigInt: Decimal.Decimal.neg (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.neg) def Decimal.neg(d: Decimal) -> Decimal: Decimal.Decimal.abs (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.abs) def Decimal.abs(d: Decimal) -> Decimal: Decimal.Decimal.is_zero (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.is_zero) def Decimal.is_zero(d: Decimal) -> Bool: Decimal.Decimal.add (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.add) def Decimal.add(a: Decimal, b: Decimal) -> Decimal: Decimal.Decimal.sub (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.sub) def Decimal.sub(a: Decimal, b: Decimal) -> Decimal: Decimal.Decimal.mul (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.mul) def Decimal.mul(a: Decimal, b: Decimal) -> Decimal: Decimal.Decimal.cmp (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.cmp) def Decimal.cmp(a: Decimal, b: Decimal) -> Cmp: Decimal.Decimal.quot (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.quot) # The quotient of a division whose divisor is known to be nonzero. def Decimal.quot(m: Maybe<&1, Big.BigInt & Big.BigInt>) -> Big.BigInt: Decimal.Decimal.divk.m (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.divk.m) # (remainder is zero, quotient) of u / k, for a nonzero k. def Decimal.divk.m(m: Maybe<&1, Big.BigInt & Big.BigInt>) -> Bool & Big.BigInt: Decimal.Decimal.divk (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.divk) def Decimal.divk(u: Big.BigInt, k: U32) -> Bool & Big.BigInt: Decimal.Decimal.is_one (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.is_one) def Decimal.is_one(u: Big.BigInt) -> Bool: Decimal.Decimal.lowest.fix (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.lowest.fix) def Decimal.lowest.fix(neg: Bool, n: Big.BigInt, d: Big.BigInt) -> Big.BigInt & Big.BigInt: Decimal.Decimal.lowest.den (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.lowest.den) def Decimal.lowest.den(n: Big.BigInt, +d: Big.BigInt) -> Big.BigInt & Big.BigInt: Decimal.Decimal.lowest.by (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.lowest.by) def Decimal.lowest.by(n: Big.BigInt, d: Big.BigInt, +g: Big.BigInt) -> Big.BigInt & Big.BigInt: Decimal.Decimal.lowest (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.lowest) # n / d in lowest terms with a positive denominator; d must be nonzero. def Decimal.lowest(+n: Big.BigInt, +d: Big.BigInt) -> Big.BigInt & Big.BigInt: Decimal.Decimal.frac.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.frac.go) # Each step divides d by 2 or 5 and scales n to match, so a d of D digits # needs fewer than 4D steps; f is that bound. def Decimal.frac.go(f: Nat, n: Big.BigInt, k: Nat, one: Bool, t2: Bool & Big.BigInt, t5: Bool & Big.BigInt) -> Maybe<&2, Decimal>: Decimal.Decimal.frac.run (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.frac.run) def Decimal.frac.run(p: Big.BigInt & Big.BigInt) -> Maybe<&2, Decimal>: Decimal.Decimal.frac.if (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.frac.if) def Decimal.frac.if(z: Bool, n: Big.BigInt, d: Big.BigInt) -> Maybe<&2, Decimal>: Decimal.Decimal.from_fraction (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.from_fraction) # n / d at the smallest exact scale, or None when d is zero or the decimal # expansion does not terminate (d has a prime factor other than 2 and 5). def Decimal.from_fraction(n: Big.BigInt, +d: Big.BigInt) -> Maybe<&2, Decimal>: Decimal.Decimal.div_exact (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.div_exact) # a / b exactly, at the smallest scale that holds it; None for a zero # divisor or a repeating quotient (use Rational for those). def Decimal.div_exact(a: Decimal, b: Decimal) -> Maybe<&2, Decimal>: Decimal.Decimal.normalize.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.normalize.go) def Decimal.normalize.go(s: Nat, u: Big.BigInt, qr: Bool & Big.BigInt) -> Decimal: Decimal.Decimal.normalize (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.normalize) # The same value at the smallest scale: 1.500 is 1.5, 0.00 is 0. def Decimal.normalize(d: Decimal) -> Decimal: Decimal.Decimal.rescale.keep (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.rescale.keep) def Decimal.rescale.keep(z: Bool, q: Big.BigInt, t: Nat) -> Maybe<&2, Decimal>: Decimal.Decimal.rescale.cut (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.rescale.cut) def Decimal.rescale.cut(t: Nat, m: Maybe<&1, Big.BigInt & Big.BigInt>) -> Maybe<&2, Decimal>: Decimal.Decimal.rescale.if (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.rescale.if) def Decimal.rescale.if(up: Bool, u: Big.BigInt, +s: Nat, +t: Nat) -> Maybe<&2, Decimal>: Decimal.Decimal.rescale (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.rescale) # The same value at scale t, or None when that would drop a nonzero digit: # rescale(1.5, 2n) is 1.50; rescale(1.25, 1n) is None, never 1.2 or 1.3. def Decimal.rescale(d: Decimal, +t: Nat) -> Maybe<&2, Decimal>: Decimal.Decimal.show.split (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.show.split) def Decimal.show.split(+s: Nat, +ds: String) -> String: Decimal.Decimal.show.point (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.show.point) # Digits with a point s places from the right, zero-padded to one whole digit. def Decimal.show.point(+s: Nat, +ds: String) -> String: Decimal.Decimal.show.sign (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.show.sign) def Decimal.show.sign(neg: Bool, body: String) -> String: Decimal.Decimal.show (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Decimal.show) # Plain notation with every scale digit: -12.50, 0.001, 7. Never an exponent. def Decimal.show(d: Decimal) -> String: Decimal.Class (https://jend.leeeet.dev/definition.txt?path=bend-kit-bignum@0.1.0.0/decimal.bend&name=Class) # A character of a number. type Class is Data: Digit{code: U32} Minus{} Plus{} Point{} Expo{} Other{} More: https://jend.leeeet.dev/packages/bend-kit-bignum.txt?definitions_offset=100