09-11-2022, 12:32 AM
Well guess what? I've been away for a bit. Straight jackets aren't as simple to slip out of as they used to be. Lucky for me, mine was made in China.
So I've been fiddling around with a new improved method of string division. My hunch was it would be about twice as fast on calculating pi in this thread. That would have made it about 35% faster than treebeard's routine. Well that hunch was exceeded significantly, to a 700% speed increase! My old code ran pi in the last loop of 160 digits in 14 seconds on my clunky machine, [b]but this new routine can do it in just 2![/]
Pete
So I've been fiddling around with a new improved method of string division. My hunch was it would be about twice as fast on calculating pi in this thread. That would have made it about 35% faster than treebeard's routine. Well that hunch was exceeded significantly, to a 700% speed increase! My old code ran pi in the last loop of 160 digits in 14 seconds on my clunky machine, [b]but this new routine can do it in just 2![/]
Code: (Select All)
'Jack's Ramanujan's Pi Estimator with Pete's String Math Routines.
WIDTH 175, 42
_SCREENMOVE 0, 0
DIM SHARED sqrt$, limit&&, betatest%
betatest% = 0
DIM AS STRING sum, f, f4, f4k, c1, c2, c3, c34k, t1, t2, t3
DIM AS LONG k, k4
DIM t AS DOUBLE
limit&& = 150: square_root "8", sqrt$ ' Limit must be as many or more digits than the max digits of the returned value for pi.
FOR pete% = 0 TO 16
limit&& = pete% + 10 + pete% * 8
t = TIMER
c1 = "1103"
c2 = "26390"
c3 = "396"
f = "1"
f4k = "1"
sum = "1103"
c34k = "1"
k4 = 0
t1 = c3
t2 = c3
sm t1, "*", t2, c3
t1 = c3
t2 = c3
sm t1, "*", t2, c3
FOR k = 1 TO limit&& / (7.984)
t1 = f
sm STR$(k), "*", t1, f
IF betatest% THEN PRINT "results = "; f: SLEEP
t1 = f: t2 = f
sm t1, "*", t2, f4
IF betatest% THEN PRINT "results = "; f4: SLEEP
t1 = f4: t2 = f4
sm t1, "*", t2, f4
IF betatest% THEN PRINT "results = "; f4: SLEEP
t1 = c34k
sm c3, "*", t1, c34k
IF betatest% THEN PRINT "results = "; c34k: SLEEP
t1 = STR$(k4 + 1)
t2 = f4k
sm t1, "*", t2, f4k
IF betatest% THEN PRINT "results = "; f4k: SLEEP
t1 = STR$(k4 + 2)
t2 = f4k
sm t1, "*", t2, f4k
IF betatest% THEN PRINT "results = "; f4k: SLEEP
t1 = STR$(k4 + 3)
t2 = f4k
sm t1, "*", t2, f4k
IF betatest% THEN PRINT "results = "; f4k: SLEEP
t1 = STR$(k4 + 4)
t2 = f4k
sm t1, "*", t2, f4k
IF betatest% THEN PRINT "results = "; f4k: SLEEP
k4 = k4 + 4
t1 = STR$(k)
sm t1, "*", c2, t2
IF betatest% THEN PRINT "results = "; t2: SLEEP
sm c1, "+", t2, t1
IF betatest% THEN PRINT "results = "; t1: SLEEP
sm f4k, "*", t1, t2
IF betatest% THEN PRINT "results = "; t2: SLEEP
sm f4, "*", c34k, t1
IF betatest% THEN PRINT "results = "; t1: SLEEP
sm t2, "/", t1, t3
IF betatest% THEN PRINT "divide results = "; t3: SLEEP
t1 = sum
sm t1, "+", t3, sum
IF betatest% THEN PRINT "sum = "; sum: SLEEP
CALL pi(t1, sum, k)
NEXT
COLOR 14, 0: PRINT "Ramanujan pi = "; MID$("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481", 1, 11 + (k - 2) * 8)
COLOR 7, 0
t = TIMER - t
PRINT "Time:"; t: PRINT
NEXT pete%
END
SUB pi (t1$, sum$, k)
REM square_root "8", sqrt$
IF betatest% THEN PRINT "sqrt Pi # = "; sqrt$: SLEEP
t2$ = "9801"
sm sqrt$, "/", t2$, t3$
IF betatest% THEN PRINT "Pi # = "; t3$: SLEEP
sm t3$, "*", sum$, t2$
IF betatest% THEN PRINT "Pi # = "; t2$: SLEEP
sm t1$, "/", t2$, t3$
IF betatest% THEN PRINT "Pi # = "; t3$: SLEEP
sm "1", "/", t2$, t1$
IF betatest% THEN PRINT "Pi # = "; t1$: SLEEP
PRINT "loop #"; LTRIM$(STR$(k));: LOCATE , 10: PRINT " pi = "; MID$(t1$, 1, 11 + (k - 1) * 8);: COLOR 8, 0: PRINT MID$(t1$, 11 + (k - 1) * 8 + 1, 4): COLOR 7, 0
END SUB
DEFINT A-Z
SUB sm (s_var1$, operator$, s_var2$, runningtotal$)
DIM AS _INTEGER64 a, c, aa, cc, s, ss
stringmatha$ = s_var1$: stringmathb$ = s_var2$
SELECT CASE operator$
CASE "+", "-"
GOSUB string_add_subtract_new
CASE "*"
GOSUB string_multiply_new
CASE "/"
GOSUB string_divide_new
CASE ELSE
PRINT "Error, no operator selected. operator$ = "; operator$: END
END SELECT
EXIT SUB
string_divide_new:
q$ = "": az$ = stringmathb$: bz$ = stringmatha$
DO ' Falx loop.
'Strip off neg(s) and determine quotent sign.
IF LEFT$(az$, 1) = "-" THEN az$ = MID$(az$, 2): q$ = "-"
IF LEFT$(bz$, 1) = "-" THEN bz$ = MID$(bz$, 2): IF q$ = "-" THEN q$ = "" ELSE q$ = "-"
' Quick results for divisor 1 or 0.
IF az$ = "0" THEN q$ = "0": EXIT DO
IF az$ = "1" THEN q$ = bz$: EXIT DO
IF bz$ = "0" THEN q$ = "Division by zero not possible.": EXIT DO
' Determine decimal direction. -1 to left, +1 to right.
gl% = 0: string_compare az$, bz$, gl%
IF gl% = 1 THEN ' Divisor is larger than dividend so decimal moves to the left.
div_decimal% = -1 ' Move decimal point to the left.
ELSEIF gl% = -1 THEN
div_decimal% = 1 ' Move decimal point to the right.
ELSE
' Divisor and dividend are the same number.
q$ = q$ + "1": EXIT DO
END IF
divisor_ratio_dividend% = gl%
' Strip off decimal point(s) and determine places in these next 2 routines.
dp&& = 0: dp2&& = 0: j2&& = 0
temp&& = INSTR(az$, ".")
IF temp&& THEN
az$ = MID$(az$, 1, temp&& - 1) + MID$(az$, temp&& + 1)
IF temp&& = 1 THEN
DO UNTIL LEFT$(az$, 1) <> "0" ' Strip off any leading zeros on divisor only.
az$ = MID$(az$, 2)
dp&& = dp&& + 1
LOOP
dp&& = dp&& + 1
ELSE
dp&& = -(temp&& - 2)
END IF
ELSE
dp&& = -(LEN(az$) - 1)
END IF
temp&& = INSTR(bz$, ".")
IF temp&& THEN
bz$ = MID$(bz$, 1, temp&& - 1) + MID$(bz$, temp&& + 1)
IF temp&& = 1 THEN
DO UNTIL LEFT$(bz$, 1) <> "0" ' Strip off any leading zeros on divisor only.
bz$ = MID$(bz$, 2)
dp2&& = dp2&& + 1
LOOP
dp2&& = dp2&& + 1
ELSE
dp2&& = -(temp&& - 2)
END IF
ELSE
dp2&& = -(LEN(bz$) - 1)
END IF
dp&& = ABS(dp&& - dp2&&)
' Adjust decimal place for instances when divisor is larger than remainder.
IF MID$(az$, 1, 1) > MID$(bz$, 1, 1) THEN
dp&& = dp&& - div_decimal%
ELSEIF MID$(az$, 1, 1) = MID$(bz$, 1, 1) THEN
IF divisor_ratio_dividend% = 1 THEN
dp&& = dp&& - div_decimal%
END IF
END IF
origbz$ = bz$
' Determine length of divisor and dividend to begin initial long divison step.
gl% = 2: string_compare az$, MID$(bz$, 1, LEN(az$)) + STRING$(LEN(az$) - LEN(bz$), "0"), gl%
divisor_ratio_dividend% = gl%
IF gl% = 1 AND MID$(bz$, 1, 1) <> "0" THEN
bz$ = MID$(bz$, 1, LEN(az$) + 1) + STRING$(LEN(az$) + 1 - LEN(bz$), "0")
ELSE
bz$ = MID$(bz$, 1, LEN(az$)) + STRING$(LEN(az$) - LEN(bz$), "0")
END IF
' Long divison loop. Mult and subtraction of dividend and remainder.
k&& = 0
DO
SELECT CASE MID$(az$, 1, 1)
CASE IS < MID$(bz$, 1, 1)
adj_rem_len% = 0
CASE IS = MID$(bz$, 1, 1)
gl% = 2: string_compare az$, MID$(bz$, 1, LEN(az$)), gl%
IF gl% = 1 THEN adj_rem_len% = 1 ELSE adj_rem_len% = 0
CASE IS > MID$(bz$, 1, 1)
adj_rem_len% = 1
END SELECT
IF j2&& = 0 THEN j2&& = LEN(az$) + adj_rem_len%
DO
IF LEN(az$) > LEN(bz$) THEN
w3&& = 0: runningtotal$ = bz$: stringmathb$ = "0"
EXIT DO
END IF
IF LEN(az$) = LEN(bz$) THEN
gl% = 2: string_compare az$, bz$, gl%
IF gl% = 1 THEN
w3&& = 0: runningtotal$ = bz$: stringmathb$ = "0"
EXIT DO
END IF
END IF
SELECT CASE LEN(bz$)
CASE IS > 2
w3&& = VAL(MID$(bz$, 1, 2 + adj_rem_len%)) \ VAL(MID$(az$, 1, 2))
CASE ELSE
w3&& = VAL(MID$(bz$, 1, 1 + adj_rem_len%)) \ VAL(MID$(az$, 1, 1))
END SELECT
IF w3&& < 9 THEN w3&& = w3&& + 1 ELSE IF w3&& = 10 THEN w3&& = 9
DO
stringmatha$ = az$: stringmathb$ = LTRIM$(STR$(w3&&))
GOSUB string_multiply_new
IF bz$ = "" THEN BEEP: BEEP
gl% = 2: string_compare runningtotal$, bz$, gl%
IF gl% <= 0 OR w3&& = 0 THEN EXIT DO
w3&& = w3&& - 1
LOOP
stringmatha$ = bz$: stringmathb$ = runningtotal$
operator$ = "-": GOSUB string_add_subtract_new
EXIT DO
LOOP
j2&& = j2&& + 1
drop$ = "0": MID$(drop$, 1, 1) = MID$(origbz$, j2&&, 1)
IF runningtotal$ <> "0" THEN remainder$ = runningtotal$ ELSE remainder$ = ""
bz$ = remainder$ + drop$
w3$ = LTRIM$(STR$(w3&&))
temp$ = ""
IF div_decimal% = -1 THEN
IF dp&& AND k&& = 0 THEN
q$ = q$ + "." + STRING$(dp&& - 1, "0")
IF w3&& = 0 THEN w3$ = ""
END IF
END IF
IF div_decimal% >= 0 THEN
IF dp&& = k&& THEN
temp$ = "."
END IF
END IF
q$ = q$ + w3$ + temp$
' Check to terminate
IF div_decimal% = -1 THEN
' Decimal to left.
IF remainder$ = "" AND MID$(origbz$, j2&&, 1) = "" OR LEN(q$) >= limit&& + 8 THEN EXIT DO
ELSE
' Decimal to right.
IF remainder$ = "" AND MID$(origbz$, j2&&, 1) = "" AND k&& >= dp&& OR LEN(q$) >= limit&& + 8 THEN EXIT DO
END IF
IF INKEY$ = " " THEN EXIT DO
k&& = k&& + 1
LOOP
EXIT DO
LOOP
IF RIGHT$(q$, 1) = "." THEN runningtotal$ = MID$(q$, 1, LEN(q$) - 1) ELSE runningtotal$ = q$
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$ = ""
' Addition and subtraction of digits.
DO
i&& = i&& + s
x1$ = MID$(a$, LEN(a$) - i&& + 1, s)
x2$ = MID$(b$, LEN(b$) - i&& + 1, s)
IF LEN(x2$) > LEN(x1$) THEN SWAP x1$, 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 ' a will never be less than 0.
tmp$ = LTRIM$(STR$(a))
z$ = STRING$(LEN(x1$) - 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.
' Multiplication of digits.
DO
h&& = h&& + s: i&& = 0
x2$ = MID$(b$, LEN(b$) - h&& + 1, s)
DO
i&& = i&& + s
x1$ = MID$(a$, LEN(a$) - i&& + 1, s)
a = VAL(x1$) * VAL(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$
LOOP UNTIL i&& >= LEN(a$) AND c = 0
jj&& = jj&& + 1
IF jj&& > 1 THEN
ii&& = 0: cc = 0
aa$ = holdaa$
bb$ = z$ + STRING$((jj&& - 1) * s, "0")
' Addition only of digits.
DO
ii&& = ii&& + ss
xx1$ = MID$(aa$, LEN(aa$) - ii&& + 1, ss)
xx2$ = MID$(bb$, LEN(bb$) - ii&& + 1, ss)
IF LEN(xx1$) < LEN(xx2$) THEN SWAP xx1$, xx2$
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 STRING$(LEN(z$), "0") = z$ OR z$ = "" OR z$ = "0" THEN z$ = "0" ELSE z$ = sign$ + z$
decimal% = 0: sign$ = ""
runningtotal$ = z$
RETURN
END SUB
SUB string_compare (stringmatha$, stringmathb$, gl%)
compa$ = stringmatha$: compb$ = stringmathb$ ' So original variables do not get changed.
DO
WHILE -1 ' Falx loop.
IF gl% = 2 THEN EXIT WHILE ' For bypassing sign and decimal adjustments when only positive non-decimal numbers are being evaluated.
' 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
SELECT CASE INSTR(compa$, ".")
CASE IS > INSTR(compb$, ".")
gl% = 1
CASE IS = INSTR(compb$, ".")
IF compa$ = compb$ THEN
gl% = 0
ELSEIF compa$ < compb$ THEN gl% = -1
ELSE
gl% = 1
END IF
CASE IS < INSTR(compb$, ".")
gl% = -1
END SELECT
EXIT DO
END IF
EXIT WHILE
WEND
' Remove leading zeros if any.
DO UNTIL LEFT$(compa$, 1) <> "0"
compa$ = MID$(compa$, 2)
LOOP
IF compa$ = "" THEN compa$ = "0"
DO UNTIL LEFT$(compb$, 1) <> "0"
compb$ = MID$(compb$, 2)
LOOP
IF compb$ = "" THEN compb$ = "0"
' 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
DEFINT A-Z
SUB square_root (x$, sqrt$)
oldy$ = "": sqrt$ = "": custom_limit&& = limit&& + 50
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
sm z$, "-", k$, runningtotal$
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
sm sqrt$, "*", "2", y$
y$ = y$ + LTRIM$(STR$(j&&))
ELSE
y$ = LTRIM$(STR$(j&&))
END IF
sm y$, "*", LTRIM$(STR$(j&&)), runningtotal$
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
sm oldy$, "*", LTRIM$(STR$(j&& - h%)), runningtotal$
IF STRING$(LEN(z$), "0") = z$ AND runningtotal$ = "0" AND i&& >= LEN(decx$) THEN EXIT DO
IF dpx&& = 0 THEN ' Limited to && size unless converted to string.
IF i&& >= LEN(decx$) THEN
dpx&& = INT(LEN(decx$) / 2 + .5)
IF dpx&& = 0 THEN dpx&& = -1
END IF
END IF
IF betatest% < -1 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%))
sm oldy$, "*", LTRIM$(STR$(j&& - h%)), runningtotal$
k$ = runningtotal$
IF betatest% < -1 THEN PRINT "Remainder "; z$; " minus "; k$; " = ";
EXIT FOR
END IF
oldy$ = y$
NEXT
i&& = i&& + 2
IF LEN(z$) >= custom_limit&& THEN EXIT DO
x$ = x$ + "00"
LOOP
IF dpx&& THEN
sqrt$ = MID$(sqrt$, 0, dpx&& + 1) + "." + MID$(sqrt$, dpx&& + 1)
END IF
END SUB
Pete