; Multi Precision Library v.1.1 ; Large Integer = {Int:Sign, UInt:LenInUInts, UInts:LSword..MSword} ; = little endian, signed magnitude (not 2's complement!) ; TODO: ; MP_TML(z,y,x,H,L) truncated multiplitaction: words L..H of the product ; MP_RCP(y,n,x) n-bit reciprocal ; MP_MPW(z,y,x,m) modular power: z <- Mod(y**x,m) ; primality tests, Legendre/Jacobi symbol ; update-reuse ints: MP_ADD(x,x,y), MP_SUB(x,y,x)... MP_Init() ; Initialize Multi Precision Library bits(n) { ; Binary representation of Int64 n>=0 Return n>1 ? bits(n>>1) . n&1 : n } MP_PowIpp(ByRef y, V32, U32) { ; y <- V32 ** U32, left-to-right exponent scan If U32 < 1 Return MP_SET(y,1) MP_SET(y,V32) b := SubStr(bits(U32),2) ; bits of the exponent from MS-1..0 Loop Parse, b { MP_MUL(z,y,y) ; z := y*y If A_LoopField ; next exponent bit MP_MulIpp(y,z,V32) ; y := z*x (V32) <- faster when x is small Else MP_CPY(y,z) ; y := z } } MP_POW(ByRef y, ByRef x, U32) { ; y <- x ** U32, left-to-right exponent scan If U32 < 1 Return MP_SET(y,1) b := SubStr(bits(U32),2) ; bits of the exponent from MS-1..0 MP_CPY(y,x) Loop Parse, b { MP_MUL(z,y,y) ; z := y*y If A_LoopField ; next exponent bit MP_MUL(y,z,x) ; y := z*x Else MP_CPY(y,z) ; y := z } } MP_POW2(ByRef y, ByRef x, U32) { ; y <- x ** U32, Right-to-left expoent scan MP_SET(y,1), MP_CPY(u,x) Loop { If (U32 & 1) MP_MUL(z,y,u), MP_CPY(y,z) ; y *= x (u) If (U32 >>= 1) MP_MUL(z,u,u), MP_CPY(u,z) ; x *= x (u) Else Return } } MP_CMP(ByRef x, ByRef y, ByRef eq="") { ; -0+ for x <=> y, eq = #equal MS words Global CMPpp eq := 0 SX := NumGet(x,0,"Int"), SY := NumGet(y,0,"Int") If (SX < SY) Return -1 If (SX > SY) Return 1 LX := NumGet(x,4), LY := NumGet(y,4) If (LX < LY) Return -SX If (LX > LY) Return SX Return SX*dllcall(&CMPpp,"Int",LX, "UInt*",eq, "UInt",&x+8, "UInt",&y+8, "CDECL Int") ; same sign, length } MP_SFT(ByRef y, ByRef x, s) { ; s>0: y <- x << s, s<0: y <- x >> -s Global SFL, SFR, LEN L8 := NumGet(x,4) If (s > 0) { ; shift left offs := s//32, s &= 31 VarSetCapacity(y,(L8+offs)*4+8,0) NumPut(NumGet(x,0,"Int"),y) ; sign NumPut(L8+offs,y,4) ; new length dllcall(&SFL, "UInt",&y+8+4*offs, "Int",L8, "UInt",&x+8, "UInt",s, "CDECL") Return } ; shift right s := -s, offs := s//32, s &= 31 If (offs >= L8) { ; too large shift: nothing remains VarSetCapacity(y,12,0) NumPut(1,y), NumPut(1,y,4) Return } VarSetCapacity(y,(L8-offs)*4+8,0) NumPut(NumGet(x,0,"Int"),y) ; sign dllcall(&SFR, "UInt",&y+8, "Int",L8-offs, "UInt",&x+8+4*offs, "UInt",s, "CDECL") NumPut(dllcall(&LEN,"Int",L8-offs,"UInt",&y+8, "CDECL Int"), y, 4) } MP_ADD(ByRef z, ByRef y, ByRef x) { ; z <- y + x Global CMPpp, ADDpp, SUBpp, LEN SX := NumGet(x,0,"Int"), SY := NumGet(y,0,"Int") LX := NumGet(x,4), LY := NumGet(y,4), LZ := LX > LY ? LX : LY If (SX = SY) { ; ADD VarSetCapacity(z, LZ*4+12) ; room for carry If (LY > LX) dllcall(&ADDpp,"UInt",&z+8, "Int",LY,"UInt",&y+8, "Int",LX,"UInt",&x+8, "CDECL") Else dllcall(&ADDpp,"UInt",&z+8, "Int",LX,"UInt",&x+8, "Int",LY,"UInt",&y+8, "CDECL") NumPut(SX,z) ; set sign(z) NumPut(dllcall(&LEN,"Int",LZ+1,"UInt",&z+8, "CDECL Int"), z, 4) Return } ; SUBTRACT NumPut(1,x), NumPut(1,y) ; set both positive c := MP_CMP(x,y,eq) ; compare, find same MS part eq -= eq = LZ ; leave at least one word VarSetCapacity(z,(LZ-eq)*4+8,0) ; no room needed for equal MS parts (fill 0 for x=y) If (c = 0) ; x = y NumPut(1,z), NumPut(1,z,4) ; z <- 0 Else If (c < 0) { ; x < y dllcall(&SUBpp,"UInt",&z+8, "Int",LY-eq,"UInt",&y+8, "Int",LX-eq,"UInt",&x+8, "CDECL") NumPut(Sy,z) ; sign(z) <- Sy } Else { ; x > y dllcall(&SUBpp,"UInt",&z+8, "Int",LX-eq,"UInt",&x+8, "Int",LY-eq,"UInt",&y+8, "CDECL") NumPut(Sx,z) ; sign(z) <- Sx } NumPut(dllcall(&LEN,"Int",LZ,"UInt",&z+8, "CDECL Int"), z, 4) NumPut(Sx,x), NumPut(Sy,y) ; reset both signs } MP_SUB(ByRef z, ByRef y, ByRef x) { ; z <- y - x SX := NumGet(x,0,"Int") NumPut(-SX,x) ; x <- (-x) MP_ADD(z,y,x) ; z <- y + (-x) NumPut( SX,x) ; reset sign(x) } MP_MUL(ByRef z, ByRef y, ByRef x) { ; z <- y * x Global MULpp, LEN SX := NumGet(x,0,"Int"), SY := NumGet(y,0,"Int") LX := NumGet(x,4), LY := NumGet(y,4), LZ := LX + LY VarSetCapacity(z, LZ*4+8, 0) dllcall(&MULpp,"UInt",&z+8, "Int",LY,"UInt",&y+8, "Int",LX,"UInt",&x+8, "CDECL") NumPut(dllcall(&LEN,"Int",LZ,"UInt",&z+8, "CDECL Int"), z, 4) NumPut(Sy*Sx,z) ; sign(z) <- Sy*Sx } MP_DIV(ByRef q, ByRef r, ByRef y, ByRef x) { ; q <- y/x, r <- Mod(y,x), sign(q) = SY*SX, sign(r) = SY Global DIVpq, LEN, CPY SX := NumGet(x,0,"Int"), SY := NumGet(y,0,"Int") LX := NumGet(x,4), LY := NumGet(y,4) If (Lx = 1) { ; Single digit x If (NumGet(x,8) = 0) Return "ERROR: Divide by 0" rem := MP_DivIpp(q, y, NumGet(x,8)) VarSetCapacity(r,12) ; put rem in MP format NumPut(SY,r), NumPut(1,r,4), NumPut(rem,r,8) NumPut(Sy*Sx,q) ; set lengths, signs Return } ; Multi-digit x If (MP_CMP(y,x) < 0) { ; y < x VarSetCapacity(q,12,0) NumPut(SY*Sx,q), NumPut(1,q,4) ; q <- 0 MP_CPY(r,y) ; r <- y Return } ; Multi-digits, y >= x LQ := LY > LX ? LY-LX+1 : 1 VarSetCapacity(q, LQ*4+ 8, 0) ; q initialized to all 0! VarSetCapacity(r, LY*4+12, 0) ; r <- y, 0-padded on both ends dllcall(&CPY, "UInt",&r+8, "UInt",&y+8, "Int",LY*4, "CDECL") dllcall(&DIVpq,"UInt",&q+8, "Int",LY,"UInt",&r+8, "Int",LX,"UInt",&x+8, "CDECL") NumPut(dllcall(&LEN,"Int",LQ,"UInt",&q+8, "CDECL Int"), q, 4) NumPut(dllcall(&LEN,"Int",LX,"UInt",&r+8, "CDECL Int"), r, 4) NumPut(Sy*Sx,q), NumPut(Sy,r) ; sign(q) <- Sy*Sx, sign(r) <- Sy } MP_GCD(ByRef g, ByRef c, ByRef d, ByRef x, ByRef y) { ; Extended shifting Euclidean GCD = g = c*x + d*y Global xGCD, CPY If (MP_IS0(x)) { MP_CPY(g,y), MP_SET(c,0), MP_SET(d,1) Return } If (MP_IS0(y)) { MP_CPY(g,x), MP_SET(c,1), MP_SET(d,0) Return } L := ((MP_LEN(x) > MP_LEN(y) ? MP_LEN(x) : MP_LEN(y)) + 3) * 4 ; temp length in bytes VarSetCapacity(Z, 6*L, 0) dllcall(&CPY, "UInt", &Z, "UInt",&x, "Int",MP_LEN(x)*4+8, "CDECL") ; copy input dllcall(&CPY, "UInt",&Z+L, "UInt",&y, "Int",MP_LEN(y)*4+8, "CDECL") ; copy destroyed in xGCD dllcall(&xGCD, "UInt*",f,"UInt*",a,"UInt*",b, "UInt",&Z,"UInt",&Z+L ; do the work , "UInt",&Z+2*L,"UInt",&Z+3*L,"UInt",&Z+4*L,"UInt",&Z+5*L) s := NumGet(f+0,4)*4+8, VarSetCapacity(g,s) ; copy result from buffer dllcall(&CPY, "UInt",&g, "UInt",f, "Int",s, "CDECL") s := NumGet(a+0,4)*4+8, VarSetCapacity(c,s) dllcall(&CPY, "UInt",&c, "UInt",a, "Int",s, "CDECL") s := NumGet(b+0,4)*4+8, VarSetCapacity(d,s) dllcall(&CPY, "UInt",&d, "UInt",b, "Int",s, "CDECL") } MP_AddIpp(ByRef y, ByRef x, I32) { ; add a 32-bit integer (pos+pos) to x Global AddIpp L8 := NumGet(x,4) VarSetCapacity(y,L8*4+12) ; one extra word for carry c := dllcall(&AddIpp, "UInt",&y+8, "Int",L8, "UInt",&x+8, "UInt",I32, "CDECL UInt") NumPut(1,y) ; positive NumPut(c>0 ? L8+1 : L8,y,4) ; true length } MP_SubIpp(ByRef y, ByRef x, I32) { ; subtract a 32-bit integer (pos+pos) from x Global SubIpp, LEN L8 := NumGet(x,4) If (L8 < 2) { VarSetCapacity(y,12) d := NumGet(x,8,"UInt") - I32 s := d < 0 ? -1 : 1 NumPut(s,y), NumPut(1,y,4), NumPut(s*d,y,8) Return } VarSetCapacity(y,L8*4+8) ; no borrow c := dllcall(&SubIpp, "UInt",&y+8, "Int",L8, "UInt",&x+8, "UInt",I32, "CDECL UInt") NumPut(1,y) ; positive NumPut(dllcall(&LEN,"Int",L8,"UInt",&y+8, "CDECL Int"), y, 4) } MP_MulIpp(ByRef y, ByRef x, I32) { ; multiply x with max 32-bit integer (pos*pos) Global MulIpp L8 := NumGet(x,4) VarSetCapacity(y,L8*4+12) ; one extra word for carry c := dllcall(&MulIpp,"UInt",&y+8, "Int",L8, "UInt",&x+8, "UInt",I32, "CDECL UInt") NumPut(1,y) ; positive NumPut(c>0 ? L8+1 : L8,y,4) ; true length } MP_DivIpp(ByRef y, ByRef x, U32) { ; y := x // 32-bit integer (pos/pos), RETURN remainder Global LEN, DivIpp L8 := NumGet(x,4) VarSetCapacity(y,L8*4+8) r := dllcall(&DivIpp,"UInt",&y+8, "Int",L8, "UInt",&x+8, "UInt",U32, "CDECL UInt") NumPut(1,y) ; positive NumPut(dllcall(&LEN,"Int",L8,"UInt",&y+8, "CDECL Int"), y, 4) Return r } MP_Cpy(ByRef y, ByRef x) { ; y <- x Global CPY L8 := NumGet(x,4) VarSetCapacity(y,L8*4+8) dllcall(&CPY, "UInt",&y, "UInt",&x, "Int",L8*4+8, "CDECL") } MP_Set(ByRef x, h) { ; x <- string (hex, decimal integer, double precision float) Global U32toHex Static D52 := 4503599627370496.0, d := 0x1234567890123456, mk = 0xFFFFFFFFFFFFF If (SubStr(h,1,1) = "-") sign := -1, h := SubStr(h,2) ; negative Else sign := 1 ; positive If (SubStr(h,1,2) = "0x") { ; arbitrary long hex L8 := (StrLen(h)+5)//8 VarSetCapacity(x,L8*4+8) Loop % L8-1 NumPut("0x" . SubStr(h,1-A_Index*8,8), x, 4+A_Index*4) NumPut(SubStr(h,1,StrLen(h)+8-L8*8), x, 4+L8*4) NumPut(L8,x,4) } Else If h contains e,. ; decimal double { If (h <= D52) ; 52-bit precise AHK conversion MP_Set(x, Round(h)) ; sign fixed at the end Else { NumPut(h,d,0,"Double") e := (NumGet(d,6,"Short")>>4) - 1075 ; power_of_2 exponent (0x3ff+52) f := NumGet(d,0,"Int64") & mk | D52 ; fraction 1..2 * 2.**-52 If e < 11 MP_Set(x, f<> 32 fl := f & 0xffffffff el := e & 31, ek := e >> 5 If (el < 12) { ; 2 words VarSetCapacity(x,16+4*ek,0) NumPut(2+ek,x,4) NumPut(fl<>(32-el), x ,12+4*ek) } Else { ; 3 words VarSetCapacity(x,20+4*ek,0) NumPut(3+ek,x,4) NumPut(fl<>(32-el), x ,12+4*ek) NumPut(fm>>(32-el), x ,16+4*ek) } } } } Else If (StrLen(h) < 19) ; decimal integer If (h > 0xffffffff) { VarSetCapacity(x,16) ; 63 bits NumPut(h & 0xffffffff,x,8) NumPut(h>>32,x,12) NumPut(2,x,4) } Else { ; 32 bits VarSetCapacity(x,12) NumPut(h,x,8) NumPut(1,x,4) } Else { ; > 18 digits d := Mod(StrLen(h)-1,9) + 1 ; 1..9 MP_Set(x,SubStr(h,1,d)) ; MS 1..9 digits StringTrimLeft h, h, d Loop % StrLen(h)//9 { MP_MulIpp(y, x, 1000000000) MP_AddIpp(x, y, SubStr(h,1,9)) StringTrimLeft h, h, 9 } } NumPut(sign,x) } MP_Hex(ByRef x, tab="") { ; HEX representation of MP integer x, tab before every 8 digits Global U32toHex, U32to8Hex Static S := "12345678" L8 := NumGet(x,4) VarSetCapacity(h,3+L8*8) DllCall(&U32toHex, "Str",h, "UInt",NumGet(x,4+L8*4), "CDECL") h := NumGet(x)=1 ? "0x" . h : "-0x" . h Loop % L8-1 DllCall(&U32to8Hex, "UInt",&S, "UInt",NumGet(x,L8*4+4-A_Index*4), "CDECL"), h .= tab . S Return h } MP_Dec(ByRef z, tab="") { ; DECIMAL representation of MP integer x, tab before every 9 digits Static d9 := 1000000000 MP_CPY(x,z) ; copy of input (destroyed) sign := NumGet(x) VarSetCapacity(d,NumGet(x,4)*10) ; allocate enough memory Loop { c := MP_DivIpp(y, x, d9) ; no leading 0's If MP_IS0(y) Break d := SubStr(c+d9,-8) . tab . d ; attach to the left with leaging 0's c := MP_DivIpp(x, y, d9) ; no leading 0's If MP_IS0(x) Break d := SubStr(c+d9,-8) . tab . d ; pad-left, prepend } Return (sign = 1 ? "" : "-") . c . tab . d } MP_LEN(ByRef x) { Return NumGet(x,4) } MP_IS0(ByRef x) { Return NumGet(x,4)=1 && NumGet(x,8)=0 } PI(digits) { ; Newton's method, 2 accurate bits/iteration, less rounding errors, < 905 million digits VarSetCapacity(y,digits*1.3,Asc("0")) MP_SET(x, 3 . y) ; initial estimate pi = 3 MP_CPY(y,x) Loop { i := 2*A_Index-1 ; for better speed: start with a large i and good initial value MP_SET(n,i*i) MP_MUL(z,y,n) MP_SET(d,4*(i+1)*(i+2)) ; up to 63 bits, i < 1.4 * 2**30, up to 1.4*2**31 accurate bits MP_DIV(y,n,z,d) ; the remainder in n can be used for rounding: fewer guard digits MP_ADD(z,x,y) MP_CPY(x,z) If (MP_LEN(y)<2) ; last few terms can be floats Break } Return SubStr(MP_DEC(x),1,digits) } PI0(digits) { ; Newton's method, little faster, for less than 20,000 digits VarSetCapacity(y,digits+sqrt(2*digits),Asc("0")) ; digits+sqrt(digits) is expected to be OK MP_SET(x, 3 . y) ; x = estimate of pi, x0 = 3 MP_CPY(y,x) ; y = current term to be added Loop { i := 2*A_Index-1 MP_MulIpp(z,y,i*i) ; 32-bit UInt parameter d := 4*(i+1)*(i+2) ; i < 2**15 ==> accuracy < 2**16 bits =~ 19,728 digits r := MP_DivIpp(w,z,d) ; remainder used for rounding: fewer guard digits MP_AddIpp(y,w,r>=d//2) MP_ADD(z,x,y) MP_CPY(x,z) If (MP_LEN(y) < 2) Break } Return SubStr(MP_DEC(x),1,digits) } SQT(value,digits) { ; Newton iteration, value <= 16 digits integer VarSetCapacity(z,digits,Asc("0")) StringLeft z, z, digits ; trailing 0's a = %value%%z%%z% ; scaled input s := Round(sqrt(value)*1.e16, 1) ; float form, to have more than 18 digits StringTrimRight s, s, 2 ; remove ".0" from end s .= z ; pad with 0's StringTrimRight s, s, 16 ; initial value MP_SET(V, a) MP_SET(X, s) Loop { MP_DIV(y,z,V,X) MP_ADD(z,X,y) MP_SFT(X,z,-1) If MP_CMP(X,y) = 0 Break } Return SubStr(MP_DEC(x),1,digits) } Factorial(n) { ; 0 <= n < 2**32 AHK integer ==> string of decimal digits If n < 4 Return SubStr("1261",n,1) MP_Set(x,n), i := n Loop % n//2-2 MP_MulIpp(y,x,--i) ,MP_MulIpp(x,y,--i) MP_MulIpp(y, x, i=4 ? 6 : 24) Return MP_Dec(y) } Factorial0(n) { ; shorter code MP_Set(result, 1) Loop %n% MP_MulIpp(tmpVal, result, A_Index) ,MP_Cpy(result, tmpVal) Return MP_Dec(result) } MCode(ByRef code, hex) { ; allocate memory and write Machine Code there VarSetCapacity(code,StrLen(hex)//2) Loop % StrLen(hex)//2 NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char") } MP_Init() { ; INITIALIZE global machine code functions GLOBAL MCode(CPY,"568B74241085F67E118B4C240C8B4424088A11881040414E75F75EC3") ; ~memcpy, copy BYTES MCode(LEN,"8B442404EB0A8B4C2408833C810077054879F333C040C3") MCode(SFL,"558BEC8B450C568B7508576A205A2B551433FF85C07E2489450C8B4510538B188B4D14D3E38BCA0BDF891E8B3883C604D3EF" . "83C004FF4D0C75E45B893E5F5E5DC3") MCode(SFR,"558BEC8B551053568B7508578B7D0C6A208BCFC1E102582B451433DB03F103D185FF7E1F897D0C8B4D1483EA048B3AD3EF83" . "EE048BC80BFB893E8B1AD3E3FF4D0C75E45F895EFC5E5B5DC3") MCode(UDIV,"8B4424048B5424088B4C2410F774240C8911C3") ; ErrorLevel = 0xc0000095: Integer Overflow MCode(ADC, "33D28B4C240C8B010344240883D2000344240483D2008911C3") ; x+y+*c, c <- carry MCode(SBB, "33D28B4C240C8B4424042B0183D2002B44240883D2008911C3") ; x-y-*b, b <- borrow MCode(MulIpp,"558BEC518365FC008B4D08578B7D0C85FF7E2153568B75108B06F7651433DB83C6040345FC13D3890183C1044F8955FC75E6" . "5E5B8B45FC89015FC9C3") MCode(DivIpp,"558BEC83EC0C8365FC00578B7D0C4F78398D45FC538B5D1089450C8B4508568D34B82BD88B45FC8945F88B04338945F48B45" . "F48B55F88B4D0CF77514891189064F83EE0485FF7DDC5E5B8B45FC5FC9C3") MCode(AddIpp,"558BEC8B45148B4D08568B750C85F67E1F8B5510578B3A03F8893983C20483C1043BF8730533C040EB0233C04E75E65F8901" . "5E5DC3") MCode(SubIpp,"558BEC8B550C85D27E2C8B45108B4D08568B302B751489318B3083C10483C0043B75147309C7451401000000EB048365140" . "04A75DC5E8B45145DC3") MCode(CMPpp,"558BEC8B550C8B450883220048535657781C8B75148B7D108D0C862BFE8B1C0F3B197511FF024883E90485C07DEF33C05F5E" . "5B5DC38B4D10C1E0028B0C08390C301BC083E00248EBE7") MCode(ADDpp,"558BEC83EC108B45148365FC0085C053568B7508578B7D107E3B8B5D188D4DFC894DF08945F88B038945F48B0789450833D2" . "8B4DF08B010345F483D20003450883D2008911890683C60483C70483C304FF4DF875D18B450C2B451485C07E2D8D4DFC894D148BD88B07" . "89450833D28B4D148B0183C00083D20003450883D2008911890683C60483C7044B75DB8B45FC5F89065E5BC9C3") MCode(SUBpp,"558BEC83EC148B45148365FC0085C053568B7508578B7D107E3B8B5D188D4DFC894DEC8945F88B038945F48B078945F033D2" . "8B4DEC8B45F02B0183D2002B45F483D2008911890683C60483C70483C304FF4DF875D18B450C2B451485C07E2D8D4DFC894D0C8BD88B07" . "89451433D28B4D0C8B45142B0183D20083E80083D2008911890683C60483C7044B75DB5F5E5BC9C3") MCode(MULpp,"558BEC8B451483EC0C85C07E628B4D08538B5D18568B751057894D142BF18945F48B450C8B4D1433D285C08955FC7E2B8945" . "F88B040EF72333FF0345FC13D701018B3983C1043BF8730533C040EB0233C003D0FF4DF88955FC75D88345140483C30483EE04FF4DF489" . "1175B55F5E5BC9C3") MCode(DIVpp,"558BEC83EC288B4D1856578B7D148B44B9FC0FBDD08955FC6A1F5E2BF28B54B9F88B4DFCD3EA8BCED3E08975ECD1EA0BD08B" . "450C3BC78955E88945F00F8C210100008B4D102BC78D048189450C8B45082BC1538945D8EB038B4D108B5DF0C1E3028D740BFC8B068B76" . "FC03D98B4DFC8BD0D3EA8B4DEC895DE48B1BD3E38B4DFCD3EE8B4DECD3E0D1EAD1EE0BD30BF03B55E88955F88975E073168D45148945F4" . "8B45E08B55F88B4DF4F775E88911EB0383C8FF836514008365F80085FF8945F47E328B750C8B4DF88B45188B0488F765F433C903451413" . "D18B0E3BC81BDBF7DB2BC803DAFF45F8890E83C604397DF8895D147CD18B45148B4DE43901744233DB3BFB895D147E368B750C8D451489" . "45DC8B45188B04988945F88B068945E033D28B4DDC8B010345F883D2000345E083D200891189064383C6043BDF7CD3FF4DF48B45E48320" . "008B550CFF4DF08B45D88B4DF4836D0C04397DF0890C100F8DF6FEFFFF5B5F5EC9C3") ; shortest code 359 bytes MCode(DIVpq,"558BEC83EC2C538B5D1856578B7D148B44BBFC0FBDC88B54BBF8894DFC6A1F592B4DFC8BF2894DF48B4DFCD3EE8B4DF4D3E0" . "D3E2D1EE0BF083FF028975E48955E87E0E8B44BBF48B4DFCD3E8D1E80945E88B450C3BC78945EC0F8C300100002BC7C1E0028945F88B5D" . "EC8B4D10C1E3028D740BFC8B068B76FC03D98B4DFC8BD0D3EA8B4DF4895DE08B1BD3E38B4DFCD3EE8B4DF4D3E0D1EAD1EE0BD30BF03B55" . "E48955F08975DC732A8D451489450C8B45DC8B55F08B4D0CF775E4891189450CF765E88945D48B4514403BD07609FF4D0CEB04834D0CFF" . "836514008365F00085FF7E388B45F88B4D108D34088B4DF08B45188B0488F7650C33C903451413D18B0E3BC81BDBF7DB2BC803DAFF45F0" . "890E83C604397DF0895D147CD18B45148B4DE03901744833DB3BFB895D147E3C8B4D108D45148945D88B45F88D34088B45188B04988945" . "F08B068945DC33D28B4DD88B010345F083D2000345DC83D200891189064383C6043BDF7CD3FF4D0C8B45E08320008B55F8FF4DEC8B4508" . "8B4D0C836DF804397DEC890C020F8DD8FEFFFF5F5E5BC9C3") ; Quotient correction 404 bytes, 20..30% faster @ large args! /* MCode(DIVpr,"558BEC8B5518D9EE83EC38538B5D148B449AFC85C0567504D9C0EB2E0FBDC8894DF08B75F06A1F592BCED3E081C61F040000" . "C1E61403C08BC8C1E90C0BF1C1E0148975E48945E0DD45E08B449AF885C07504D9C1EB2E0FBDC8894DF08B55F06A1F592BCAD3E081C2FF" . "030000C1E21403C08BC8C1E90C0BD1C1E0148955E48945E0DD45E08B450CDEC13BC38945F80F8CBA010000D9E82BC3C1E002DEF18945FC" . "578B55F88B7510C1E2028D04328945F08B0085C07504D9C1EB2E0FBDC8894D0C8B7D0C6A1F592BCFD3E081C73F040000C1E71403C08BC8" . "C1E90C0BF9C1E014897DDC8945D8DD45D88D5432F88B420485C07504D9C2EB2E0FBDC8894D0C8B7D0C6A1F592BCFD3E081C71F040000C1" . "E71403C08BC8C1E90C0BF9C1E014897DD48945D0DD45D08B0285C07504D9C3EB2E0FBDC8894D0C8B550C6A1F592BCAD3E081C2FF030000" . "C1E21403C08BC8C1E90C0BD1C1E0148955CC8945C8DD45C8DEC1DEC1D8C9DD5DE08B55E481FA0000F03F0F82C800000081FA0000F04172" . "06834D0CFFEB218B4DE08BC20D0000F0FFC1E915C1E00B0BC1C1EA14B91E0400002BCAD3E889450C33FF33DB397D147E2E8B45FC03F08B" . "45188B04B8F7650C33C903C313D18B0E3BC81BDBF7DB2BC803DA890E4783C6043B7D147CDA8B75108B45F03918744633FF397D14897DF4" . "7E398D45F48945E48B45FC03F08B45188B04B88945E88B068945EC33D28B4DE48B010345E883D2000345EC83D200891189064783C6043B" . "7D147CD2FF4D0C8B45F08320008B45088B4DFC8B550C8B5D14891401FF4DF8836DFC04395DF80F8D54FEFFFF5FDDD95EDDD85BC9C3") ; 598 bytes. uses real (double) division internally. Workaround compiler bugs!! */ MCode(U32toHex,"8B542404566A1C33F6598B44240CD3E883E00F03F0750485C9750E83F80976040437EB02043088024283E90479DCC602005EC3") MCode(U32to8Hex,"8B5424046A1C598B442408D3E883E00F83F8097E040437EB02043088024283E90479E4C60200C3") MCode(xGCD, "558BEC8B551C836208008B4D2433C0408942048901894104894108830AFF8B4D2083EC20538B5D1489018941048941088B4D" . "28836108008309FF56578941048B43048B55188BC82B4A04740A3BC81BC083E00248EB234083F8027C1B8BFB8D34822BFA8B0C372B0E0F" . "85C60000004883EE0483F8027DEC33C085C00F840B0400007D228B4D1C8BC38945188B4524894D248B4D2089451C8B45288BDA8B551889" . "4D288945208B43040FBD4C8304894D148B4A040FBD748A048B7D142BFE8975EC8BF02BF185FF897D147D054E83451420408D7E023BC789" . "45EC7E426A1F592B4D142BC68D0482894DF88945F08B78FC8B4DF88B00D3EF8B4D14D3E08B4DECD1EF0BF88B048B2BC775338B45F04983" . "E8048D7E023BCF894DEC8945F07FCF8B4D148B42088B3CBBD3E08BC88BC72BC174173BC7EB0B3B0C83E912FFFFFF3B048B1BC083E00248" . "EB138D4601EB07833C830077154883F8027DF433C085C00F842A0300007D03FF4D14837D14007D054E834514208B4D148365FC008D45FC" . "8945F48B4208D3E08D7CB3088945EC8B078945F033D28B4DF48B45F02B0183D2002B45EC83D200891189078B4B048D4603413BC18945F4" . "77608D4DFC894DE86A1F592B4D142BC6894DF88B4D188D3C818B4DF88B47FC8B17D3E88B4D14D3E2D1E80BC28945EC8B45F48B04838945" . "F033D28B4DE88B45F02B0183D2002B45EC83D20089118B4DF4FF45F489048B8B430483C704403945F476B78B430433C94140EB07833C83" . "0075084883F80277F4EB038D48FF894B04837C8B04000F844C0200008B4D148365FC008D45FC8945F08B451C8B4008D3E08945EC8B4524" . "8D7CB0088B078945E833D28B4DF08B010345EC83D2000345E883D200891189078B451C8B40048D7C30018B45248B4004403BF873028BF8" . "8D46033BC78945F4776C8D4DFC894DE46A1F592B4D142BC6894DF88B4D1C8D04818945F0EB038B45F08B50FC8B4DF88B00D3EA8B4D14D3" . "E08B4DF4D1EA0BD08B45248D04888945E08B008955EC8945E833D28B4DE48B010345EC83D2000345E883D20089118B4DE0FF45F48345F0" . "04397DF4890176B08B551C8D45FC8945E86A1F8BC72BC68B0482592B4D14D3E8894DF8D1E88945E48B45248B44B8048945E033D28B4DE8" . "8B010345E483D2000345E083D20089118B4D248944B9048B45FC85C089790476098944B908FF4104EB0B837CB9040075044F8979048B4D" . "148B7D288365FC008D45FC8945E88B45208B4008D3E08945E48B44B7088945E033D28B4DE88B010345E483D2000345E083D20089118B4D" . "208944B7088B41048D5430018B4704403BD08955F473038945F48D46033B45F48945F0775D2BC68D55FC8D04818955E88945ECEB038B45" . "EC8B50FC8B4DF88B00D3EA8B4D14D3E0D1EA0BD08B45F08B04878955E48945E033D28B4DE88B010345E483D2000345E083D20089118B4D" . "F08345EC0489048F413B4DF4894DF076B68B4D208D45FC8945E48B45F48BD02BD68B14918B4DF8D3EA8D7487048B06894514D1EA8955E0" . "33D28B4DE48B010345E083D20003451483D20089118B4DFC85C989068B45F4894704760C894C8708FF4704E9C8FBFFFF833E000F85BFFB" . "FFFF8B4D2848E9B3FBFFFF8B55188B45088B4D1C89108B450C89088B45108B4D205F5E89085BC9C3") ; 1190 bytes }