Square form factorization: Difference between revisions
Content added Content deleted
(C) |
(→{{header|Wren}}: Tweaked to be closer to original C. About 40% faster than before.) |
||
Line 942: | 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. |
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 |
<lang ecmascript>import "/long" for ULong |
||
import "/big" for BigInt |
import "/big" for BigInt |
||
import "/fmt" for Fmt |
import "/fmt" for Fmt |
||
var |
var multipliers = [ |
||
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 |
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 squfof = Fn.new { |N| |
||
var s = N. |
var s = ULong.new((N.toNum.sqrt + 0.5).floor) |
||
if (s*s == N) return s |
if (s*s == N) return s |
||
for ( |
for (multiplier in multipliers) { |
||
var T = ULong |
var T = ULong |
||
var n = N |
var n = N |
||
if (n > |
if (n > ULong.largest/multiplier) { |
||
T = BigInt |
T = BigInt |
||
n = BigInt.new(n.toString) |
n = BigInt.new(n.toString) |
||
} |
} |
||
var D = n * multiplier |
var D = n * multiplier |
||
var P = D.isqrt |
var P = D.isqrt |
||
var Pprev = P |
var Pprev = P |
||
Line 968: | Line 966: | ||
var Qprev = T.one |
var Qprev = T.one |
||
var Q = D - Po*Po |
var Q = D - Po*Po |
||
var L = |
var L = (s * 8).isqrt.toSmall |
||
var B = 3 * L |
var B = 3 * L |
||
var i = 2 |
var i = 2 |
||
Line 979: | Line 977: | ||
q = Q |
q = Q |
||
Q = Qprev + b * (Pprev - P) |
Q = Qprev + b * (Pprev - P) |
||
r = Q. |
r = T.new((Q.toNum.sqrt + 0.5).floor) |
||
if ((i & 1) == 0 && r*r == Q) break |
if ((i & 1) == 0 && r*r == Q) break |
||
Qprev = q |
Qprev = q |