Category talk:Wren-big: Difference between revisions

m
→‎Source code: Now uses Wren S/H lexer.
(→‎Source code: Added support for ranges of BigInts.)
m (→‎Source code: Now uses Wren S/H lexer.)
 
(6 intermediate revisions by the same user not shown)
Line 46:
 
===Source code===
<syntaxhighlight lang="ecmascriptwren">/* Module "big.wren" */
 
import "./trait" for Comparable
Line 1,693:
static range(from, to, step) { range(from, to, step, true, from <= to) }
static range(from, to) { range(from, to, 1, true, from <= to) }
 
// Self-explanatory read only properties.
from { _rng.from }
to { _rng.to }
step { _step }
min { from.min(to) }
max { from.max(to) }
isInclusive { _rng.isInclusive }
isAscending { from <= to }
 
// Iterator protocol methods.
Line 1,935 ⟶ 1,944:
pow(i) {
if (!((i is Num) && i.isInteger)) Fiber.abort("Argument must be an integer.")
if (i == 0) return thisBigRat.copy()one
if (i == 1) return this.copy()
if (i == -1) return this.inverse
var np = _n.pow(i.abs)
var dp = _d.pow(i.abs)
Line 2,003 ⟶ 2,014:
// Converts the current instance to a Num where possible.
// Will probably lose accuracy if the numerator and/or denominator are not 'small'.
toFloat { Num_n.fromString(thistoNum / _d.toDecimal(14))toNum }
 
// Converts the current instance to an integer where possible with any fractional part truncated.
Line 2,061 ⟶ 2,072:
// Returns a string represenation of this instance in the form "i_n/d" where 'i' is an integer.
toMixedString {
var qsign = _n.isNegative /? _d"-" : ""
var rnn = _n % _d.abs
ifvar (r.isNegative) rq = -rnn / _d
return q.toString + "_" +var r.toString += "/"nn +% _d.toString
return sign + q.toString + "_" + r.toString + "/" + _d.toString
}
 
Line 2,123 ⟶ 2,135:
static phi { new("1.6180339887498948482045868343656381177203091798057628621354486227", 64) }
static sqrt2 { new("1.4142135623730950488016887242096980785696718753769480731766797380", 64) }
 
// Returns 'pi' to a given precision using the Almqvest Berndt AGM method.
// See https://rosettacode.org/wiki/Arithmetic-geometric_mean/Calculate_Pi for details.
static pi(prec) {
if (prec < 16) prec = 16
var an = BigRat.one
var bn = BigRat.half.sqrt(prec)
var tn = BigRat.half.square
var pn = BigRat.one
while (pn <= prec) {
var prevAn = an
an = (bn + an) * BigRat.half
bn = (bn * prevAn).sqrt(prec)
prevAn = prevAn - an
tn = tn - (prevAn.square * pn)
pn = pn + pn
}
var res = (an + bn).square / (tn * 4)
return BigDec.fromBigRat(res, prec)
}
 
// Returns the greater of two BigDec objects.
Line 2,238 ⟶ 2,270:
copy() { BigDec.new_(_br.copy(), _prec) }
 
// Compares this BigDec with another one'other' to enable comparison operators via Comparable trait.
compare(other) { (other is BigDec) ? _br.compare(other.br_) : _br.compare(other) }
 
// As above but compares the absolute values of the BigDecs.
compareAbs(other) { (other is BigDec) ? _br.compareAbs(other.br_) : _br.compareAbs(other) }
 
// Returns this BigDec expressed as a BigInt with any fractional part truncated.
Line 2,252 ⟶ 2,284:
// Converts the current instance to a Num where possible.
// Will probably lose accuracy for larger numbers.
toFloat { Num_br.fromString(this.toString(14))toFloat }
 
// Converts the current instance to an integer where possible with any fractional part truncated.
Line 2,270 ⟶ 2,302:
toString { toString(_prec, true, false) } // precision digits, always rounded
toDefaultString { toString(16, true, false) } // 16 digits, always rounded
 
// Private worker method for exponentiation using Taylor series.
exp_ {
var y = _br
var x = _br
var z = _br
var res = x + BigRat.one
var eps = BigRat.new(BigInt.one, BigInt.ten.pow(_prec))
var k = 2
var fact = BigRat.two
while (x.abs > eps) {
z = z * y
x = z / fact
res = res + x.round(_prec+2)
k = k + 1
fact = fact * k
}
return BigDec.fromBigRat(res, _prec)
}
 
// Returns the exponential of this instance (e ^ this) to the same precision.
exp {
if (_br.isInteger) return exp_
return (truncate/2).exp_.square * fraction.exp_
}
 
// Private worker method for natural logarithm using Taylor series.
log_ {
var y = _br
var x = (y - BigRat.one) / (y + BigRat.one)
var z = x * x
var res = BigRat.zero
var eps = BigRat.new(BigInt.one, BigInt.ten.pow(_prec))
var k = 1
while (x.abs > eps) {
res = res + (BigRat.two * x / k).round(_prec+2)
x = (x * z).round(_prec+2)
k = k + 2
}
return BigDec.new_(res, _prec)
}
 
// Returns the natural logarithm of this instance to the same precision.
log {
if (sign <= 0) Fiber.abort("Instance must be positive.")
if (this < BigDec.two) return log_
var d = this.copy()
var pow = 0
var two = BigDec.new(2, _prec)
while (d >= two) {
d = d / 2
pow = pow + 1
}
return d.log_ + two.log_ * pow
}
 
// Returns this ^ f where f may be fractional.
powf(f) {
if ((f is Num) && f.isInteger) return pow(f)
return (log * f).exp
}
}
 
9,476

edits