Category talk:Wren-big: Difference between revisions
Content added Content deleted
(→Arbitrary precision arithmetic: Change to blurb following addition of BigDec.) |
(→Source code: Added support for ranges of BigInts.) |
||
Line 1,396: | Line 1,396: | ||
return sign + str |
return sign + str |
||
} |
} |
||
// Creates and returns a range of BigInts from 'this' to 'n' with a step of 1. |
|||
// 'this' and 'n' must both be 'small' integers. 'n' can be a Num or a BigInt. |
|||
..(n) { BigInts.range(this, n, 1, true) } // inclusive of 'n' |
|||
...(n) { BigInts.range(this, n, 1, false) } // exclusive of 'n' |
|||
/* Prime factorization methods. */ |
/* Prime factorization methods. */ |
||
Line 1,652: | Line 1,657: | ||
} |
} |
||
/* BigInts contains various routines applicable to lists of big integers |
/* BigInts contains various routines applicable to lists of big integers |
||
and for creating and iterating though ranges of such numbers. */ |
|||
class BigInts { |
class BigInts is Sequence { |
||
static sum(a) { a.reduce(BigInt.zero) { |acc, x| acc + x } } |
static sum(a) { a.reduce(BigInt.zero) { |acc, x| acc + x } } |
||
static prod(a) { a.reduce(BigInt.one) { |acc, x| acc * x } } |
static prod(a) { a.reduce(BigInt.one) { |acc, x| acc * x } } |
||
static max(a) { a.reduce { |acc, x| (x > acc) ? x : acc } } |
static max(a) { a.reduce { |acc, x| (x > acc) ? x : acc } } |
||
static min(a) { a.reduce { |acc, x| (x < acc) ? x : acc } } |
static min(a) { a.reduce { |acc, x| (x < acc) ? x : acc } } |
||
// Private helper method for creating ranges. |
|||
static checkValue_(v, name) { |
|||
if (v is BigInt && v.isSmall) { |
|||
return v.toSmall |
|||
} else if (v is Num && v.isInteger && v.abs <= Num.maxSafeInteger) { |
|||
return v |
|||
} else { |
|||
Fiber.abort("Invalid value for '%(name)'.") |
|||
} |
|||
} |
|||
// Creates a range of 'small' BigInts analogous to the Range class but allowing for steps > 1. |
|||
// Use the 'ascending' parameter to check that the range's direction is as intended. |
|||
construct range(from, to, step, inclusive, ascending) { |
|||
from = BigInts.checkValue_(from, "from") |
|||
to = BigInts.checkValue_(to, "to") |
|||
step = BigInts.checkValue_(step, "step") |
|||
if (step < 1) Fiber.abort("'step' must be a positive integer.") |
|||
if (ascending && from > to) Fiber.abort("'from' cannot exceed 'to'.") |
|||
if (!ascending && from < to) Fiber.abort("'to' cannot exceed 'from'.") |
|||
_rng = inclusive ? from..to : from...to |
|||
_step = step |
|||
} |
|||
// Convenience versions of 'range' which use default values for some parameters. |
|||
static range(from, to, step, inclusive) { range(from, to, step, inclusive, from <= to) } |
|||
static range(from, to, step) { range(from, to, step, true, from <= to) } |
|||
static range(from, to) { range(from, to, 1, true, from <= to) } |
|||
// Iterator protocol methods. |
|||
iterate(iterator) { |
|||
if (!iterator || _step == 1) { |
|||
return _rng.iterate(iterator) |
|||
} else { |
|||
var count = _step |
|||
while (count > 0 && iterator) { |
|||
iterator = _rng.iterate(iterator) |
|||
count = count - 1 |
|||
} |
|||
return iterator |
|||
} |
|||
} |
|||
iteratorValue(iterate) { BigInt.small_(_rng.iteratorValue(iterate)) } |
|||
} |
} |
||