Category talk:Wren-gmp: Difference between revisions

→‎Source code (Wren): Added some more constants, 'divisor' methods and several other minor changes.
m (→‎Source code (Wren): Corrected a program comment re Mpz.probPrime.)
(→‎Source code (Wren): Added some more constants, 'divisor' methods and several other minor changes.)
Line 52:
static four { from(4) }
static five { from(5) }
static six { from(6) }
static seven { from(7) }
static eight { from(8) }
static nine { from(9) }
static ten { from(10) }
 
Line 102 ⟶ 106:
// Returns the smaller of two Mpz objects.
static min(op1, op2) {
if (!(op1 is Mpz)) op1 = from(op1)
if (!(op2 is Mpz)) op2 = from(op2)
if (op1 < op2) return op1
return op2
Line 108 ⟶ 114:
// Returns the greater of two Mpz objects.
static max(op1, op2) {
if (!(op1 is Mpz)) op1 = from(op1)
if (!(op2 is Mpz)) op2 = from(op2)
if (op1 > op2) return op1
return op2
Line 114 ⟶ 122:
// Returns the positive difference of two Mpz objects.
static dim(op1, op2) {
if (!(op1 is Mpz)) op1 = from(op1)
if (!(op2 is Mpz)) op2 = from(op2)
if (op1 >= op2) return op1 - op2
return Mpz.zero
Line 356 ⟶ 366:
max(op) { (op > this) ? set(op) : this } // maximum of this and op
clamp(min, max) { // clamps this to the interval [min, max]
if (thismin <> minmax) return setFiber.abort(min"Range cannot be decreasing.")
if (this < min) set(min) else if (this > max) return set(max)
return this.copy()
}
 
Line 450 ⟶ 460:
foreign digitsInBase(base) // as sizeInBase, always exact but slower
sizeInBits { sizeInBase(2) } // number of binary digits in this ignoring any sign
 
/* Prime factorization methods. */
 
// Private worker method for Pollard's Rho algorithm.
static pollardRho_(m, seed, c) {
var g = Fn.new { |x| x.copy(x * x).square.add(c).rem(m) }
var x = Mpz.from(seed)
var y = Mpz.from(seed)
Line 534 ⟶ 544:
while (n > 1) {
if (checkPrime && n.probPrime(15) > 0) {
factors.add(n.copy())
break
}
Line 610 ⟶ 620:
// Better for large numbers with a small number of prime factors.
static divisors2(n) {
if (n <=is zeroNum) returnn []= from(n)
var factorspf = primeFactors(n)
varif divs(pf.count == 0) return (n == 1) ? [one] : pf
forvar (parr in= factors) {[]
forif (ipf.count in== 0...divs.count1) divs.add(divs[i]*p){
arr.add([pf[0].copy(), 1])
} else {
var prevPrime = pf[0]
var count = 1
for (i in 1...pf.count) {
if (pf[i] == prevPrime) {
count = count + 1
} else {
arr.add([prevPrime.copy(), count])
prevPrime = pf[i]
count = 1
}
}
arr.add([prevPrime.copy(), count])
}
divs.sort()var divisors = []
var c = divs.countgenerateDivs
ifgenerateDivs (c= > 1)Fn.new { |currIndex, currDivisor|
forif (icurrIndex in== c-1arr..1count) {
if divisors.add(divs[i-1] == divs[i]) divscurrDivisor.removeAtcopy(i))
return
}
for (i in 0..arr[currIndex][1]) {
generateDivs.call(currIndex+1, currDivisor)
currDivisor = currDivisor * arr[currIndex][0]
}
}
returngenerateDivs.call(0, divsone)
return divisors.sort()
}
 
Line 632 ⟶ 662:
return (c <= 1) ? [] : d[0..-2]
}
 
// Returns the sum of all the divisors of 'n' including 1 and 'n' itself.
static divisorSum(n) {
if (n < 1) return zero
n = from(n)
var total = one
var power = two
while (n.isDivisible(two)) {
total.add(power)
power.mul(2)
n.div(2)
}
var i = three
while (i * i <= n) {
var sum = one
power.set(i)
while (n.isDivisible(i)) {
sum.add(power)
power.mul(i)
n.div(i)
}
total.mul(sum)
i.add(2)
}
if (n > 1) total.mul(n + 1)
return total
}
 
// Returns the number of divisors of 'n' including 1 and 'n' itself.
static divisorCount(n) {
if (n < 1) return 0
n = from(n)
var count = 0
var prod = 1
while (n.isDivisible(two)) {
count = count + 1
n.div(2)
}
prod = prod * (1 + count)
var i = three
while (i * i <= n) {
count = 0
while (n.isDivisible(i)) {
count = count + 1
n.div(i)
}
prod = prod * (1 + count)
i.add(2)
}
if (n > 2) prod = prod * 2
return prod
}
 
 
/* Methods which apply to a sequence of Mpz objects. */
Line 673 ⟶ 756:
// Returns the smaller of two Mpq objects.
static min(op1, op2) {
if (!(op1 is Mpq)) op1 = from(op1)
if (!(op2 is Mpq)) op2 = from(op2)
if (op1 < op2) return op1
return op2
Line 679 ⟶ 764:
// Returns the greater of two Mpq objects.
static max(op1, op2) {
if (!(op1 is Mpq)) op1 = from(op1)
if (!(op2 is Mpq)) op2 = from(op2)
if (op1 > op2) return op1
return op2
Line 685 ⟶ 772:
// Returns the positive difference of two Mpq objects.
static dim(op1, op2) {
if (!(op1 is Mpq)) op1 = from(op1)
if (!(op2 is Mpq)) op2 = from(op2)
if (op1 >= op2) return op1 - op2
return Mpq.zero
Line 801 ⟶ 890:
max(op) { (op > this) ? set(op) : this } // maximum of this and op
clamp(min, max) { // clamps this to the interval [min, max]
if (thismin <> minmax) return setFiber.abort(min"Range cannot be decreasing.")
if (this < min) set(min) else if (this > max) return set(max)
return this.copy()
}
 
Line 904 ⟶ 993:
// Returns the smaller of two Mpf objects.
static min(op1, op2) {
if (!(op1 is Mpf)) op1 = from(op1)
if (!(op2 is Mpf)) op2 = from(op2)
if (op1 < op2) return op1
return op2
Line 910 ⟶ 1,001:
// Returns the greater of two Mpf objects.
static max(op1, op2) {
if (!(op1 is Mpf)) op1 = from(op1)
if (!(op2 is Mpf)) op2 = from(op2)
if (op1 > op2) return op1
return op2
Line 916 ⟶ 1,009:
// Returns the positive difference of two Mpf objects.
static dim(op1, op2) {
if (!(op1 is Mpf)) op1 = from(op1)
if (!(op2 is Mpf)) op2 = from(op2)
if (op1 >= op2) return op1 - op2
return Mpf.zero
Line 1,173 ⟶ 1,268:
max(op) { (op > this) ? set(op) : this } // maximum of this and op
clamp(min, max) { // clamps this to the interval [min, max]
if (thismin <> minmax) return setFiber.abort(min"Range cannot be decreasing.")
if (this < min) set(min) else if (this > max) return set(max)
return this.copy()
}
 
Line 1,204 ⟶ 1,299:
isZero { cmpUi(0) == 0 } // returns 'true' if the current instance is zero
 
fraction { // the fractional part of this with the same sign, as a new Mpf object
var t = copy().trunc
return t.sub(this, t)
9,482

edits