What is the size limit for numbers in LC? -- and multiplying really large numbers
Geoff Canyon
gcanyon at gmail.com
Sat Sep 7 01:21:59 CEST 2013
On Fri, Sep 6, 2013 at 2:12 PM, Mark Wieder <mwieder at ahsoftware.net> wrote:
> At first glance that seems impressive, but do you have unit tests for
> this? If they're big random numbers, how do you know the answer is
> right?
>
I haven't done anything terribly thorough but:
1. I have checked each algorithm against the previous with at least a dozen
values (weakened by the fact that most of those values were strings of 9s,
since I was checking for overflows).
2. I have in all cases checked small values to see that they work.
3. I have checked the above mentioned strings of 9s to see that they
produce the correct result, because 999999...9999^2 = 9999...998000...0001
4. In response to this email I wrote a quick test that compared the result
of X * Y for 10,000 random number pairs, and found a bug :-) Turns out I
was losing leading 0s from intermediate results because of:
put char -7 to -1 of S before R
if S is 1234, then R needs 0001234 in front of it -- unless this is the
last step, obviously.
This was causing put bigTimesN7(3,-480169303) to return -144507909, when it
should be -1440507909. So I amended the routine to:
function bigTimesN7 X,Y
if char 1 of X is "-" then
put "-" into leadChar
delete char 1 of X
end if
if char 1 of Y is "-" then
if leadChar is "-" then put empty into leadChar else put "-" into
leadChar
delete char 1 of Y
end if
put (6 + length(X)) div 7 * 7 into XL
put char 1 to XL - length(X) of "000000" before X
put (6 + length(Y)) div 7 * 7 into YL
put char 1 to YL - length(y) of "000000" before y
repeat with N = XL + YL down to 15 step -7
repeat with M = max(7,N - YL) to min(XL,N - 7) step 7
add (char M - 6 to M of X) * (char N - M - 6 to N - M of Y) to S
if S > 900000019999997 then
add char -20 to -8 of S to Scarry
delete char -20 to -8 of S
end if
end repeat
put char -7 to -1 of ("0000000" & S) before R
add char -20 to -8 of S to Scarry
put char -7 to -1 of Scarry into S
delete char -7 to -1 of Scarry
end repeat
put Scarry & S before R
repeat with i = 1 to 15
if char i of R is not "0" then exit repeat
end repeat
if i > 1 then delete char 1 to i - 1 of R
return leadChar & R
end bigTimesN7
I re-ran the test routine, and now it matched 10,000 out of 10,000.
Further, I have J installed, which has its own arbitrary integer precision
math. So I had LC create some equalities to test in J:
_1130205693993682372824769249053636054878517315x =
_39214613172841811231391033x * 28821033858276318555x
1
The 1 indicates truth. J uses an underscore for negative numbers.
_212761062255119126378152174395218739555914717752x =
29931081010835427510229954x * _7108365453893795141788x
1
16252484302425344360409130220272036688212554937196254254608741748014x
= 41210326672812378812736110577510887x *
394378924279374110323599616495522x
1
855949301441168562394700712367072183965950192185909474168767594482496489254071079189423582502465412218076051576598820335380230586488256862521543786177091410608514801403738523023017426796605748996223246868232771548015847240714345129475528x
= 3334475101616757910712638639825532262558105533281027610787675417225717x
* 256696863931043262844895953384410981101116109864288869619472109587827174383484710510486108696955762610103731039938527183481016179810325410499297282915105364237276610984x
1
I think I have it now. Thanks for keeping me honest!
gc
More information about the use-livecode
mailing list