Just finished calculating pi to 30 trillion places.
#26
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![/]

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
Reply


Messages In This Thread
RE: Just finished calculating pi to 30 trillion places. - by Pete - 09-11-2022, 12:32 AM



Users browsing this thread: 8 Guest(s)