Category talk:Wren-long: Difference between revisions

→‎Source code: Various changes and tweaks to give minor performance improvements.
m (→‎Source code: Minor bug fix.)
(→‎Source code: Various changes and tweaks to give minor performance improvements.)
Line 98:
return String.fromCodePoint((c >= 65 && c <= 90) ? c + 32 : c)
}.join() }
 
 
// Private helper method to convert a lower case base string to a small integer.
Line 214 ⟶ 213:
static isInstance(n) { n is ULong }
 
// Private helper method tofor determinemodMul ifmethod a ULong is a basic primeto oravoid notoverflow.
static isBasicPrime_checkedAdd_(na, b, c) {
ifvar (!(nroom is= ULong))c n- =ULong.one - new(n)a
if (n.isOne)b return<= room) false{
if (n == two ||a n == three || n == five)a return+ trueb
} else {
if (n.isEven || n.isDivisibleBy(three) || n.isDivisibleBy(five)) return false
if (n < 49) returna true= b - room - ULong.one
}
return null // unknown if prime or not
return a
}
 
Line 241:
var next = false
while (d != 0) {
x = x.isShort ? (x * x) % n : x.modMul(x, n)
if (x.isOne) return false
if (x == nPrev) {
Line 422:
// Returns true if 'n' is a divisor of the current instance, false otherwise
isDivisibleBy(n) { (this % n).isZero }
 
// Private helper method for 'isPrime' method.
// Determines whether the current instance is prime using a wheel with basis [2, 3, 5].
// Should be faster than Miller-Rabin if the current instance is 'short' (below 2 ^ 32).
isShortPrime_ {
if (this < 2) return false
var n = this.copy()
if (n.isEven) return n == 2
if ((n%3).isZero) return n == 3
if ((n%5).isZero) return n == 5
var d = ULong.seven
while (d*d <= n) {
if ((n%d).isZero) return false
d = d + 4
if ((n%d).isZero) return false
d = d + 2
if ((n%d).isZero) return false
d = d + 4
if ((n%d).isZero) return false
d = d + 2
if ((n%d).isZero) return false
d = d + 4
if ((n%d).isZero) return false
d = d + 6
if ((n%d).isZero) return false
d = d + 2
if ((n%d).isZero) return false
d = d + 6
if ((n%d).isZero) return false
}
return true
}
 
// Returns true if the current instance is prime, false otherwise.
isPrime {
varif isbp = ULong.isBasicPrime_(this.isShort) return isShortPrime_
if (isEven || isDivisibleBy(ULong.three) || isDivisibleBy(ULong.five) ||
if (isbp != null) return isbp
isDivisibleBy(ULong.seven)) return false
var a
if (this < 2047) {
Line 469 ⟶ 502:
msb_ {
if (_hi == 0) return (_lo > 0) ? ULong.log2_(_lo).floor : 0
 
return ULong.log2_(_hi).floor + 32
}
Line 535 ⟶ 569:
}
 
// Private helper method for 'divMod', '/' and '%' methods.
// Returns a list containing the quotient and the remainder after dividing
// Uses Num division to estimate the answer and refine it until the exact answer is found.
// the current instance by a ULong.
divModdivMod_(n) {
if (!(n is ULong)) n = ULong.new(n)
if (n.isZero) Fiber.abort("Cannot divide by zero.")
// if both operands are 'small' use Num division.
if (this.isSmall && n.isSmall) {
var a = this.toNum
var b = n.toNum
return [ULong.fromSmall_((a/b).floor), ULong.fromSmall_(a%b)]
}
if (this.isZero) return [ULong.zero, ULong.zero]
if (n.isOne) return [this.copy(), ULong.zero]
if (n > this) return [ULong.zero, this.copy()]
// use Num division to estimate the answer and refine it until the exact answer is found.
var div = ULong.zero
var rem = this.copy()
Line 574 ⟶ 596:
}
return [div, rem]
}
 
// Returns a list containing the quotient and the remainder after dividing
// the current instance by a ULong.
divMod(n) {
if (!(n is ULong)) n = ULong.new(n)
if (n.isZero) Fiber.abort("Cannot divide by zero.")
if (n > this) return [ULong.zero, this.copy()]
if (n == this) return [ULong.one, ULong.zero]
if (this.isZero) return [ULong.zero, ULong.zero]
if (n.isOne) return [this.copy(), ULong.zero]
// if both operands are 'small' use Num division.
if (this.isSmall && n.isSmall) {
var a = this.toNum
var b = n.toNum
return [ULong.fromSmall_((a/b).floor), ULong.fromSmall_(a%b)]
}
return divMod_(n)
}
 
// Divides the current instance by a ULong.
/ (n) { divMod(n)[0] }
if (!(n is ULong)) n = ULong.new(n)
if (n.isZero) Fiber.abort("Cannot divide by zero.")
if (n > this || this.isZero) return ULong.zero
if (n == this) return ULong.one
if (n.isOne) return this.copy()
// if this instance is 'small' use Num division.
if (this.isSmall) {
var a = this.toNum
var b = n.toNum
return ULong.fromSmall_((a/b).floor)
}
return divMod_(n)[0]
}
 
// Returns the remainder after dividing the current instance by a ULong.
% (n) { divMod(n)[1] }
if (!(n is ULong)) n = ULong.new(n)
if (n.isZero) Fiber.abort("Cannot divide by zero.")
if (n > this) return this.copy()
if (this.isZero || n.isOne || n == this) return ULong.zero
// if this instance is 'small' use Num division
if (this.isSmall) {
var a = this.toNum
var b = n.toNum
return ULong.fromSmall_(a%b)
}
return divMod_(n)[1]
}
 
//Returns the bitwise 'and' of the current instance and another ULong.
Line 749 ⟶ 814:
if (mod.isZero) Fiber.abort("Cannot take modMul with modulus 0.")
var x = ULong.zero
var y = this % mod
n = n % mod
if (n > y) {
var t = y
y = n
n = t
}
while (n > ULong.zero) {
if ((n & 1) == 1) x = ULong.checkedAdd_(x +, y) %, mod)
y = ULong.checkedAdd_(y, <<y, 1mod) % mod
n = n >> 1
}
Line 769 ⟶ 840:
if (exp.isOdd) r = r.modMul(base, mod)
exp = exp >> 1
base = base.isShort ? base * base % mod : base.modMul(base, mod)
}
return r
Line 1,077 ⟶ 1,148:
var total = one
var power = two
while (n % 2 == 0.isEven) {
total = total + power
power = power *<< 21
n = n />> 21
}
var i = three
Line 1,104 ⟶ 1,175:
var count = 0
var prod = 1
while (n % 2 == 0.isEven) {
count = count + 1
n = n />> 21
}
prod = prod * (1 + count)
Line 1,119 ⟶ 1,190:
i = i + 2
}
if (n > 2) prod = prod *<< 21
return prod
}
Line 1,345 ⟶ 1,416:
 
// Divides the current instance by a Long.
/ (n) { divMod(n)[0] }
if (!(n is Long)) n = Long.new(n)
if (n.isZero) Fiber.abort("Cannot divide by zero.")
var d = _mag / n.mag
return Long.sigma_(_sig / n.sign, d)
}
 
// Returns the remainder after dividing the current instance by a Long.
% (n) { divMod(n)[1] }
if (!(n is Long)) n = Long.new(n)
if (n.isZero) Fiber.abort("Cannot divide by zero.")
var m = _mag % n.mag
return Long.sigma_(_sig, m)
}
 
// Returns the absolute value of 'this'.
9,485

edits