Square form factorization: Difference between revisions

→‎{{header|Wren}}: Tweaked to be closer to original C. About 40% faster than before.
(C)
(→‎{{header|Wren}}: Tweaked to be closer to original C. About 40% faster than before.)
Line 942:
 
Even so, there are two examples which fail (1000000000000000127 and 1537228672809128917) because the code is unable to process enough 'multipliers' before an overflow situation is encountered. To deal with this, the program automatically switches to BigInt to process such cases.
 
This is still 6 times faster than processing the whole lot using BigInt.
<lang ecmascript>import "/long" for ULong
import "/big" for BigInt
import "/fmt" for Fmt
 
var multipliermultipliers = [
1, 3, 5, 7, 11, 3*5, 3*7, 3*11, 5*7, 5*11, 7*11, 3*5*7, 3*5*11, 3*7*11, 5*7*11, 3*5*7*11
]
 
var squfof = Fn.new { |N|
var s = ULong.new((N.isqrttoNum.sqrt + 0.5).floor)
if (s*s == N) return s
for (kmultiplier in 0...multiplier.countmultipliers) {
var T = ULong
var n = N
if (n > TULong.largest/multiplier[k]) {
T = BigInt
n = BigInt.new(n.toString)
}
var D = n * multiplier[k]
var P = D.isqrt
var Pprev = P
Line 968 ⟶ 966:
var Qprev = T.one
var Q = D - Po*Po
var L = ((s * 28).isqrt * 2).toSmall
var B = 3 * L
var i = 2
Line 979 ⟶ 977:
q = Q
Q = Qprev + b * (Pprev - P)
r = T.new((Q.isqrttoNum.sqrt + 0.5).floor)
if ((i & 1) == 0 && r*r == Q) break
Qprev = q
9,479

edits