(08-24-2022, 02:20 AM)Jack Wrote: just for you Pete, here's the Ramanujan formula simplified
to calculate Pi to 1 million digits using Ramanujan would take 125000 iterations, it would take 20 iterations with the Gauss–Legendre algorithmCode: (Select All)Function Ramanujan# ()
Dim As Double sum, f, f4, f4k, c1, c2, c3, c4, c34k
Dim As Long k, k4
c1 = 1103
c2 = 26390
c3 = 396
f = 1
f4k = 1
sum = 1103
c34k = 1
k4 = 0
c4 = c3 * c3: c4 = c4 * c4
For k = 1 To 2
f = f * k
f4 = f * f: f4 = f4 * f4
c34k = c34k * c4
f4k = f4k * (k4 + 1) * (k4 + 2) * (k4 + 3) * (k4 + 4): k4 = k4 + 4
sum = sum + (f4k * (c1 + c2 * k)) / (f4 * c34k)
Next
Ramanujan = 1 / (2 * Sqr(2) / 9801 * sum)
End Function
@Jack
Thanks a ton for posting this. I'm not sure how long it would take me to re-acquaint myself the factoring when applied to linear equations.
Something I found interesting when converting it to string math was the precision lacking in numeric computer math balanced out the results between the square root calculation and the other larger digit division operations. For fun, I included a way to make the string square root the same digits as the numeric one. If you un-remark that '===========================> line, you will see what I mean. The numeric and string pi numbers will no longer match to the non-greyed out decimal places.
Out of curiosity, is there a way this routine can be used to calculate pi to the next 8 digits and so on? s when in the formula, n = 0, n = 1, n = 2, etc. Increasing the k loops just doesn't seem to produce that effect tot he correct output. For instance, Ram's 22-digit 2 iteration value as per an online calculator is reported as: 3.141592653589793238462
Code: (Select All)
WIDTH 160, 42
_SCREENMOVE 0, 0
DIM SHARED Ramjan$, limit&&, beta
limit&& = 16
'beta = -1
LOCATE 1, 1: PRINT "Jack's Numeric Results: ";
IF beta THEN LOCATE 5: PRINT
PRINT Ramanujan#
PRINT
LOCATE 3, 1: PRINT "Unrounded String Math Results: "; MID$(Ramjan$, 1, 17);: COLOR 8, 0: PRINT MID$(Ramjan$, 18)
COLOR 7, 0
END
FUNCTION Ramanujan# ()
DIM AS DOUBLE sum, f, f4, f4k, c1, c2, c3, c34k
DIM AS LONG k, k4
sqrt$ = "": CALL square_root("8", sqrt$, limit&&)
'sqrt$ = MID$(sqrt$, 1, 8) '=============================>
stringmatha$ = sqrt$
stringmathb$ = "9801"
operator$ = "/"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
numerator$ = runningtotal$
c1$ = "1103"
c2$ = "26390"
c3$ = "396"
f$ = "1"
f4k$ = "1"
sum$ = "1103"
c34k$ = "1"
k4$ = "0"
'----------------------
c1 = 1103
c2 = 26390
c3 = 396
f = 1
f4k = 1
sum = 1103
c34k = 1
k4 = 0
'----------------------
stringmatha$ = c3$
FOR i = 1 TO 3
stringmathb$ = c3$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
stringmatha$ = runningtotal$
NEXT
c3$ = runningtotal$: c3 = c3 * c3 * c3 * c3
IF beta THEN PRINT "c3^4 = "; runningtotal$, c3
stringmatha$ = c3$
stringmathb$ = "9801"
operator$ = "/"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
numerator$ = runningtotal$
IF beta THEN PRINT "c3^4 / 9801 = "; runningtotal$, c3 / 9801
FOR k = 1 TO 2
stringmatha$ = f$
stringmathb$ = LTRIM$(STR$(k))
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
f$ = runningtotal$: f = f * (k)
stringmatha$ = f$
stringmathb$ = f$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
f4$ = runningtotal$
stringmathb$ = runningtotal$
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
f4$ = runningtotal$: f4 = f * f: f4 = f4 * f4
stringmatha$ = c34k$
stringmathb$ = c3$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
c34k$ = runningtotal$: c34k = c34k * c3
stringmatha$ = f$
stringmathb$ = LTRIM$(STR$(k))
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
f$ = runningtotal$: f = f * k
'-------------------------
REDIM k4$(4): k4$(0) = k4$
FOR i = 1 TO 4
stringmatha$ = k4$(i - 1)
stringmathb$ = "1"
operator$ = "+"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
k4$(i) = runningtotal$
NEXT
FOR i = 1 TO 4
stringmatha$ = f4k$
stringmathb$ = k4$(i)
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
f4k$ = runningtotal$
NEXT
f4k = f4k * (k4 + 1) * (k4 + 2) * (k4 + 3) * (k4 + 4)
' Increase k4$ variable.
stringmatha$ = k4$
stringmathb$ = "4"
operator$ = "+"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
k4$ = runningtotal$: k4 = k4 + 4
' Calculate sum.
stringmatha$ = c2$
stringmathb$ = LTRIM$(STR$(k))
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
stringmatha$ = runningtotal$
stringmathb$ = c1$
IF beta THEN PRINT: PRINT "String variables c2$ k$: "; runningtotal$, c1$, " Numeric variables:"; (c2 * k), c1
operator$ = "+"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
stringmatha$ = runningtotal$
stringmathb$ = f4k$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
term1$ = runningtotal$
stringmatha$ = f4$
stringmathb$ = c34k$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
term2$ = runningtotal$
stringmatha$ = term1$
stringmathb$ = term2$
operator$ = "/"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
IF beta THEN
PRINT
COLOR 4
PRINT "term1$ / term2$: "; term1$; " / "; term2$
PRINT "term1 / term2: "; ((c2 * k) + c1) * f4k; "/"; c34k * f4
PRINT "String division = "; runningtotal$, "Numeric division ="; ((c2 * k) + c1) / c34k * f4
COLOR 7, 0
END IF
stringmatha$ = runningtotal$
stringmathb$ = sum$
operator$ = "+"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
sum$ = runningtotal$
sum = sum + (f4k * (c1 + c2 * (k))) / (f4 * c34k)
IF beta THEN
PRINT
COLOR 2, 0: PRINT "String SQR(8) = "; sqrt$, " Numeric 2 * SQR(2) ="; 2 * SQR(2)
PRINT "String sum$ = "; sum$, " Numeric sum ="; sum
stringmatha$ = "9801"
stringmathb$ = sum$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
PRINT "String 9801 * sum$ = "; runningtotal$, "Numeric 9801 * sum ="; 9801 * sum
COLOR 7, 0
END IF
NEXT
stringmatha$ = sqrt$
stringmathb$ = "9801"
operator$ = "/"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
stringmatha$ = runningtotal$
IF beta THEN COLOR 6, 0: PRINT: PRINT "String sqr 8 / 9801: "; runningtotal$, " Numeric 2 * SQR(2) / 9801 ="; (2 * SQR(2)) / 9801
stringmathb$ = sum$
operator$ = "*"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
IF beta THEN PRINT "String denominator:"; runningtotal$, " Numeric denominator: "; (2 * SQR(2) / 9801 * sum)
stringmatha$ = "1"
stringmathb$ = runningtotal$
operator$ = "/"
CALL string_math(stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
IF beta THEN PRINT "String pi = "; runningtotal$, " Numeric pi ="; 1 / (2 * SQR(2) / 9801 * sum): COLOR 7, 0
Ramjan$ = runningtotal$
IF beta THEN LOCATE 1, 28
Ramanujan = 1 / (SQR(8) / 9801 * sum)
END FUNCTION
SUB square_root (x$, sqrt$, limit&&)
oldy$ = ""
IF INSTR(x$, ".") THEN
decx$ = MID$(x$, 1, INSTR(x$, ".") - 1)
x$ = MID$(x$, 1, INSTR(x$, ".") - 1) + MID$(x$, INSTR(x$, ".") + 1)
IF LEN(x$) = 1 THEN x$ = x$ + "0"
ELSE
decx$ = x$
END IF
j&& = LEN(decx$)
' VAL() okay, one character eval.
IF VAL(RIGHT$(LTRIM$(STR$(j&&)), 1)) / 2 = VAL(RIGHT$(LTRIM$(STR$(j&&)), 1)) \ 2 THEN
i&& = 1 ' Even number length.
ELSE
i&& = 0 ' Odd number length.
END IF
DO
stringmatha$ = z$: stringmathb$ = k$
string_math z$, "-", k$, runningtotal$, terminating_decimal%, limit&&
z$ = runningtotal$ + (MID$(x$, i&&, 2))
IF LEFT$(z$, 1) = "0" THEN z$ = MID$(z$, 2) ' Remove leading zeros
oldy$ = ""
FOR j&& = 1 TO 10
IF i&& > 1 THEN
string_math sqrt$, "*", "2", y$, terminating_decimal%, limit&&
y$ = y$ + LTRIM$(STR$(j&&))
ELSE
y$ = LTRIM$(STR$(j&&))
END IF
string_math y$, "*", LTRIM$(STR$(j&&)), runningtotal$, terminating_decimal%, limit&&
string_compare runningtotal$, z$, gl%
IF gl% > -1 THEN
IF gl% = 0 THEN
h% = 0: oldy$ = y$ ' Perfect square division.
ELSE
h% = 1
END IF
string_math oldy$, "*", LTRIM$(STR$(j&& - h%)), runningtotal$, terminating_decimal%, limit&&
IF STRING$(LEN(z$), "0") = z$ AND runningtotal$ = "0" AND i&& >= LEN(decx$) THEN EXIT DO
IF dp&& = 0 THEN ' Limited to && size unless converted to string.
IF i&& >= LEN(decx$) THEN
dp&& = INT(LEN(decx$) / 2 + .5)
IF dp&& = 0 THEN dp&& = -1
END IF
END IF
IF betatest% THEN PRINT "Sqrt "; sqrt$; " * 2 = ";: COLOR 2, 0: PRINT LTRIM$(STR$(VAL(sqrt$) * 2));: COLOR 7, 0: PRINT LTRIM$(STR$(j&& - h%)); " * "; LTRIM$(STR$(j&& - h%)); " ="; VAL(oldy$) * (j&& - h%)
sqrt$ = sqrt$ + LTRIM$(STR$(j&& - h%))
string_math oldy$, "*", LTRIM$(STR$(j&& - h%)), runningtotal$, terminating_decimal%, limit&&
k$ = runningtotal$
IF betatest% THEN PRINT "Remainder "; z$; " minus "; k$; " = ";
EXIT FOR
END IF
oldy$ = y$
NEXT
IF betatest% THEN
string_math stringmatha$, "-", stringmathb$, runningtotal$, terminating_decimal%, limit&&
PRINT runningtotal$; " sqrt = "; sqrt$
END IF
i&& = i&& + 2
IF LEN(z$) >= limit&& THEN EXIT DO
x$ = x$ + "00"
LOOP
IF dp&& THEN
sqrt$ = MID$(sqrt$, 0, dp&& + 1) + "." + MID$(sqrt$, dp&& + 1)
END IF
END SUB
SUB string_math (stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
DIM AS _INTEGER64 a, c, aa, cc, s, ss
SELECT CASE operator$
CASE "+", "-"
GOSUB string_add_subtract_new
CASE "*"
GOSUB string_multiply_new
CASE "/"
GOSUB string_divide
CASE ELSE
PRINT "Error, no operator selected. operator$ = "; operator$: END
END SELECT
EXIT SUB
string_divide:
terminating_decimal% = 0: divsign% = 0: divremainder& = 0: divremainder$ = "": divplace& = 0: divplace2& = 0: quotient$ = "": divcarry& = 0
divbuffer& = LEN(stringmathb$) - LEN(stringmatha$)
IF divbuffer& < 0 THEN divbuffer& = 0
d2dividend$ = stringmatha$
d1divisor$ = stringmathb$
IF LEFT$(d1divisor$, 1) = "0" AND LEN(d1divisor$) = 1 THEN PRINT "Division by zero not allowed.": divsign% = 0: EXIT SUB
IF LEFT$(d1divisor$, 1) = "-" THEN divsign% = -1: d1divisor$ = MID$(d1divisor$, 2)
IF LEFT$(d2dividend$, 1) = "-" THEN
IF divsign% THEN
divsign% = 0
ELSE
divsign% = -1
END IF
d2dividend$ = MID$(d2dividend$, 2)
END IF
IF INSTR(d1divisor$, ".") <> 0 THEN
DO UNTIL RIGHT$(d1divisor$, 1) <> "0"
d1divisor$ = MID$(d1divisor$, 1, LEN(d1divisor$) - 1) ' Strip off trailing zeros
LOOP
divplace& = LEN(d1divisor$) - INSTR(d1divisor$, ".")
d1divisor$ = MID$(d1divisor$, 1, INSTR(d1divisor$, ".") - 1) + MID$(d1divisor$, INSTR(d1divisor$, ".") + 1) ' Strip off decimal point.
DO UNTIL LEFT$(d1divisor$, 1) <> "0"
d1divisor$ = MID$(d1divisor$, 2) ' Strip off leading zeros for divisors smaller than .1
LOOP
END IF
IF INSTR(d2dividend$, ".") <> 0 THEN
d2dividend$ = d2dividend$ + STRING$(divplace& - LEN(d2dividend$) - INSTR(d2dividend$, "."), "0") ' Add any zeros based on the length of dividend at decimal - length of divisor at decimal. If less than zero, nothing added.
divplace2& = INSTR(d2dividend$, ".")
DO UNTIL RIGHT$(d2dividend$, 1) <> "0"
d2dividend$ = MID$(d2dividend$, 1, LEN(d2dividend$) - 1) ' Strip off trailing zeros
LOOP
d2dividend$ = MID$(d2dividend$, 1, INSTR(d2dividend$, ".") - 1) + MID$(d2dividend$, INSTR(d2dividend$, ".") + 1) ' Strip off decimal point.
ELSE
d2dividend$ = d2dividend$ + STRING$(divplace&, "0") ' Add any zeros based on the length of dividend at decimal - length of divisor at decimal. If less than zero, nothing added.
divplace& = 0
END IF
DO
DO
divremainder& = divremainder& + 1: divremainder$ = divremainder$ + MID$(d2dividend$, divremainder&, 1)
IF MID$(d2dividend$, divremainder&, 1) = "" THEN
IF divremainder$ = STRING$(LEN(divremainder$), "0") AND LEN(quotient$) > LEN(d2dividend$) THEN
divflag% = -1
terminating_decimal% = -1
EXIT DO
END IF
divcarry& = divcarry& + 1
IF divcarry& = 1 THEN divplace3& = divremainder& - 1
IF divcarry& > limit&& + 1 + divbuffer& THEN
divflag% = -2: EXIT DO
END IF
divremainder$ = divremainder$ + "0" ' No more digits to bring down.
END IF
IF LEN(divremainder$) > LEN(d1divisor$) OR LEN(divremainder$) = LEN(d1divisor$) AND divremainder$ >= d1divisor$ THEN EXIT DO
quotient$ = quotient$ + "0"
LOOP
IF divflag% THEN divflag% = 0: EXIT DO
FOR div_i% = 9 TO 1 STEP -1
stringmatha$ = LTRIM$(STR$(div_i%)): stringmathb$ = d1divisor$
GOSUB string_multiply_new ' Gets runningtotal$
tempcutd$ = divremainder$ ' divremainder$ can be 00 or other leading zero values.
DO
IF LEN(tempcutd$) = 1 THEN EXIT DO
IF LEFT$(tempcutd$, 1) = "0" THEN
tempcutd$ = MID$(tempcutd$, 2)
ELSE
EXIT DO
END IF
LOOP
IF LEN(tempcutd$) > LEN(runningtotal$) OR LEN(tempcutd$) = LEN(runningtotal$) AND runningtotal$ <= tempcutd$ THEN EXIT FOR
NEXT
quotient$ = quotient$ + LTRIM$(STR$(div_i%))
stringmatha$ = LTRIM$(STR$(div_i%)): stringmathb$ = d1divisor$
GOSUB string_multiply_new ' Gets runningtotal$
stringmatha$ = divremainder$: stringmathb$ = runningtotal$
operator$ = "-": GOSUB string_add_subtract_new
divremainder$ = runningtotal$
LOOP
IF divplace& = 0 AND divplace2& = 0 THEN divplace& = divplace3&
IF divplace2& THEN divplace& = divplace& + divplace2& - 1
IF quotient$ = "" THEN divplace& = 0 ' dividend is zero.
IF divplace& OR divplace2& THEN
quotient$ = MID$(quotient$, 1, divplace&) + "." + MID$(quotient$, divplace& + 1)
DO UNTIL RIGHT$(quotient$, 1) <> "0"
quotient$ = MID$(quotient$, 1, LEN(quotient$) - 1) ' Strip off trailing zeros
LOOP
IF RIGHT$(quotient$, 1) = "." THEN quotient$ = MID$(quotient$, 1, LEN(quotient$) - 1) ' Strip off abandoned decimal.
END IF
DO UNTIL LEFT$(quotient$, 1) <> "0"
quotient$ = MID$(quotient$, 2) ' Strip off leading zeros
LOOP
IF quotient$ = "" THEN quotient$ = "0": divsign% = 0
stringmathb$ = quotient$: quotient$ = ""
IF stringmathb$ = "overflow" THEN divsign% = 0: EXIT SUB
runningtotal$ = stringmathb$: stringmathb$ = ""
IF divsign% THEN runningtotal$ = "-" + runningtotal$
IF stringmathround$ <> "" THEN runningtotal$ = runningtotal$ + stringmathround$
RETURN
string_add_subtract_new:
a1$ = stringmatha$: b1$ = stringmathb$
s = 18: i&& = 0: c = 0
a$ = stringmatha$: b$ = stringmathb$: op$ = operator$
IF op$ = "-" THEN
IF LEFT$(b$, 1) = "-" THEN b$ = MID$(b$, 2) ELSE b$ = "-" + b$
END IF
IF INSTR(a$, ".") <> 0 OR INSTR(b$, ".") <> 0 THEN
decimal% = -1
IF INSTR(a$, ".") <> 0 THEN
dec_a&& = LEN(MID$(a$, INSTR(a$, ".") + 1))
a$ = MID$(a$, 1, INSTR(a$, ".") - 1) + MID$(a$, INSTR(a$, ".") + 1)
END IF
IF INSTR(b$, ".") <> 0 THEN
dec_b&& = LEN(MID$(b$, INSTR(b$, ".") + 1))
b$ = MID$(b$, 1, INSTR(b$, ".") - 1) + MID$(b$, INSTR(b$, ".") + 1)
END IF
' Line up decimal places by inserting trailing zeros.
IF dec_b&& > dec_a&& THEN
j&& = dec_b&&
a$ = a$ + STRING$(dec_b&& - dec_a&&, "0")
ELSE
j&& = dec_a&&
b$ = b$ + STRING$(dec_a&& - dec_b&&, "0")
END IF
END IF
IF LEFT$(a$, 1) = "-" OR LEFT$(b$, 1) = "-" THEN
IF LEFT$(a$, 1) = "-" AND LEFT$(b$, 1) = "-" THEN
sign$ = "--": a$ = MID$(a$, 2): b$ = MID$(b$, 2)
ELSE
IF LEFT$(a$, 1) = "-" THEN a$ = MID$(a$, 2): sign_a$ = "-"
IF LEFT$(b$, 1) = "-" THEN b$ = MID$(b$, 2): sign_b$ = "-"
IF LEFT$(a1$, 1) = "-" THEN a1_x$ = MID$(a1$, 2) ELSE a1_x$ = a1$
IF LEFT$(b1$, 1) = "-" THEN b1_x$ = MID$(b1$, 2) ELSE b1_x$ = b1$
string_compare a1_x$, b1_x$, gl%
IF gl% < 0 THEN
IF LEN(sign_b$) THEN sign$ = "-": SWAP a$, b$
ELSE
IF LEN(sign_a$) THEN sign$ = "-": SWAP sign_a$, sign_b$
END IF
END IF
END IF
z$ = ""
DO
i&& = i&& + s
x1$ = MID$(a$, LEN(a$) - i&& + 1, s)
x2$ = MID$(b$, LEN(b$) - i&& + 1, s)
zeros% = LEN(x1$): IF LEN(x2$) > zeros% THEN zeros% = LEN(x2$)
a = VAL(sign_a$ + x1$) + VAL(sign_b$ + x2$) + c
IF x1$ + x2$ = "" AND c = 0 THEN EXIT DO
c = 0
IF a > VAL(STRING$(s, "9")) THEN a = a - 10 ^ s: c = 1
IF a < 0 THEN a = a + 10 ^ s: c = -1
tmp$ = LTRIM$(STR$(a))
z$ = STRING$(zeros% - LEN(tmp$), "0") + tmp$ + z$
LOOP
IF decimal% THEN
z$ = MID$(z$, 1, LEN(z$) - j&&) + "." + MID$(z$, LEN(z$) - j&& + 1)
END IF
' Remove any leading zeros.
DO
IF LEFT$(z$, 1) = "0" THEN z$ = MID$(z$, 2) ELSE EXIT DO
LOOP
IF z$ = "" OR z$ = "0" THEN z$ = "0" ELSE z$ = LEFT$(sign$, 1) + z$
runningtotal$ = z$
sign$ = "": sign_a$ = "": sign_b$ = "": i&& = 0: j&& = 0: decimal% = 0: c = 0
RETURN
string_multiply_new:
z$ = "": sign$ = "": mult&& = 0: h&& = 0: i&& = 0: j&& = 0: c = 0: decimal% = 0
zz$ = "": ii&& = 0: jj&& = 0
s = 8: ss = 18
a$ = stringmatha$: b$ = stringmathb$
IF INSTR(a$, "-") <> 0 OR INSTR(b$, "-") <> 0 THEN
IF INSTR(a$, "-") <> 0 AND INSTR(b$, "-") <> 0 THEN
a$ = MID$(a$, 2): b$ = MID$(b$, 2)
ELSE
IF INSTR(a$, "-") <> 0 THEN a$ = MID$(a$, 2) ELSE b$ = MID$(b$, 2)
sign$ = "-"
END IF
END IF
IF INSTR(a$, ".") <> 0 OR INSTR(b$, ".") <> 0 THEN
decimal% = -1
IF INSTR(a$, ".") <> 0 THEN
dec_a&& = LEN(MID$(a$, INSTR(a$, ".") + 1))
a$ = MID$(a$, 1, INSTR(a$, ".") - 1) + MID$(a$, INSTR(a$, ".") + 1)
END IF
IF INSTR(b$, ".") <> 0 THEN
dec_b&& = LEN(MID$(b$, INSTR(b$, ".") + 1))
b$ = MID$(b$, 1, INSTR(b$, ".") - 1) + MID$(b$, INSTR(b$, ".") + 1)
END IF
END IF
IF LEN(a$) < LEN(b$) THEN SWAP a$, b$ ' Needed so x1$ is always the largest for leading zero replacements.
DO
h&& = h&& + s: i&& = 0
x2$ = MID$(b$, LEN(b$) - h&& + 1, s)
WHILE -1
i&& = i&& + s
x1$ = MID$(a$, LEN(a$) - i&& + 1, s)
a = VAL(sign_a$ + x1$) * VAL(sign_b$ + x2$) + c
c = 0
tmp$ = LTRIM$(STR$(a))
IF LEN(tmp$) > s THEN c = VAL(MID$(tmp$, 1, LEN(tmp$) - s)): tmp$ = MID$(tmp$, LEN(tmp$) - s + 1)
z$ = STRING$(LEN(x1$) - LEN(tmp$), "0") + tmp$ + z$
IF i&& >= LEN(a$) AND c = 0 THEN EXIT WHILE
WEND
jj&& = jj&& + 1
IF jj&& > 1 THEN
ii&& = 0: cc = 0
aa$ = holdaa$
bb$ = z$ + STRING$((jj&& - 1) * s, "0")
DO
ii&& = ii&& + ss
xx1$ = MID$(aa$, LEN(aa$) - ii&& + 1, ss)
xx2$ = MID$(bb$, LEN(bb$) - ii&& + 1, ss)
aa = VAL(xx1$) + VAL(xx2$) + cc
IF xx1$ + xx2$ = "" AND cc = 0 THEN EXIT DO ' Prevents leading zeros.
cc = 0
IF aa > VAL(STRING$(ss, "9")) THEN aa = aa - 10 ^ ss: cc = 1
tmp$ = LTRIM$(STR$(aa))
zz$ = STRING$(LEN(xx1$) - LEN(tmp$), "0") + tmp$ + zz$
LOOP
DO WHILE LEFT$(zz$, 1) = "0"
IF LEFT$(zz$, 1) = "0" THEN zz$ = MID$(zz$, 2)
LOOP
IF zz$ = "" THEN zz$ = "0"
holdaa$ = zz$
ELSE
holdaa$ = z$ + STRING$(jj&& - 1, "0")
END IF
z$ = "": zz$ = ""
LOOP UNTIL h&& >= LEN(b$)
z$ = holdaa$
IF decimal% THEN
DO UNTIL LEN(z$) >= dec_a&& + dec_b&&
z$ = "0" + z$
LOOP
z$ = MID$(z$, 0, LEN(z$) - (dec_a&& + dec_b&& - 1)) + "." + MID$(z$, LEN(z$) - (dec_a&& + dec_b&&) + 1)
DO UNTIL RIGHT$(z$, 1) <> "0" AND RIGHT$(z$, 1) <> "."
z$ = MID$(z$, 1, LEN(z$) - 1)
LOOP
END IF
IF z$ = "" OR z$ = "0" THEN z$ = "0" ELSE z$ = sign$ + z$
decimal% = 0: sign$ = ""
runningtotal$ = z$
RETURN
END SUB
SUB string_compare (compa$, compb$, gl%)
DO
' Remove trailing zeros after a decimal point.
IF INSTR(compa$, ".") THEN
DO UNTIL RIGHT$(compa$, 1) <> "0" AND RIGHT$(compa$, 1) <> "." AND RIGHT$(compa$, 1) <> "-"
compa$ = MID$(compa$, 1, LEN(compa$) - 1)
LOOP
END IF
IF INSTR(compb$, ".") THEN
DO UNTIL RIGHT$(compb$, 1) <> "0" AND RIGHT$(compb$, 1) <> "." AND RIGHT$(compb$, 1) <> "-"
compb$ = MID$(compb$, 1, LEN(compb$) - 1)
LOOP
END IF
IF MID$(compa$, 1, 2) = "-0" OR compa$ = "" OR compa$ = "-" THEN compa$ = "0"
IF MID$(compb$, 1, 2) = "-0" OR compb$ = "" OR compb$ = "-" THEN compb$ = "0"
' A - and +
IF LEFT$(compa$, 1) = "-" THEN j% = -1
IF LEFT$(compb$, 1) = "-" THEN k% = -1
IF k% = 0 AND j% THEN gl% = -1: EXIT DO
IF j% = 0 AND k% THEN gl% = 1: EXIT DO
' A decimal and non-decimal.
j% = INSTR(compa$, ".")
k% = INSTR(compb$, ".")
IF j% = 0 AND k% THEN
IF compa$ = "0" THEN gl% = -1 ELSE gl% = 1
EXIT DO
END IF
IF k% = 0 AND j% THEN
IF compb$ = "0" THEN gl% = 1 ELSE gl% = -1
EXIT DO
END IF
' Both decimals.
IF j% THEN
IF compa$ > compb$ THEN
gl% = 1
ELSEIF compa$ = compb$ THEN gl% = 0
ELSEIF compa$ < compb$ THEN gl% = -1
END IF
EXIT DO
END IF
' Both positive or both negative whole numbers.
SELECT CASE LEN(compa$)
CASE IS < LEN(compb$)
gl% = -1
CASE IS = LEN(compb$)
IF compa$ = compb$ THEN
gl% = 0
ELSEIF compa$ > compb$ THEN gl% = 1
ELSEIF compa$ < compb$ THEN gl% = -1
END IF
CASE IS > LEN(compb$)
gl% = 1
END SELECT
EXIT DO
LOOP
END SUB
Pete