Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Perpetual string math calculator.
#1
I've seen online calculators that do this:

1 / 3 * 3 = .999...

and this:

1 / 3 * 3 = 1

Obviously, the second one takes into account 1 / 3  as an infinite repetend. So I was wondering if there was some algorithm I could apply to properly round all repetend situations. Well, I punted on that concept, as to identify a repetend that goes over 10,000 digits before repeating the number sequence, simply takes too much calculation time. Not to mention how far can we go? After all, Pi is a transcendental number, so that could take an eternity... or an eternity and a half, if you're using FreeBASIC.

So, I decided to approach this problem by going old-school. Although decimals can never be depended on to divide and multiply back symmetrically, fractions can. So I designed a string math calculator system that works with numerators and denominators, but displays the results in decimal form.

This is roughed out, which means I did not put much thought into variable and line number names, tricks to speed it up, or extensive optimization. Goal #1 for me is to always get it working, and I think this is either close or does meet my first goal...

Code: (Select All)
DIM SHARED betatest%
REM betatest% = -1
WIDTH 160, 42
_SCREENMOVE 0, 0
DIM SHARED operator$, stringmatha$, stringmathb$, runningtotal$, limit&&
start:
display_as&& = 15
limit&& = 100
DO
    IF sa$ = "" OR LEN(op$) THEN
        LINE INPUT "Number: "; n$
        IF op$ = "" THEN
            sa$ = n$
        ELSE
            sb$ = n$
            GOSUB calculate
            op$ = ""
        END IF
    ELSE
        ' Input operation.
        PRINT "[+-*/]: ";
        DO
            _LIMIT 30
            mykey$ = INKEY$
            IF LEN(mykey$) THEN
                SELECT CASE mykey$
                    CASE "+", "="
                        op$ = "+": EXIT DO
                    CASE "-", "_"
                        op$ = "-": EXIT DO
                    CASE "*", "8"
                        op$ = "*": EXIT DO
                    CASE "/", "?"
                        op$ = "/": EXIT DO
                    CASE "c", "C"
                        PRINT: PRINT "Total = 0": CLEAR: GOTO start
                    CASE CHR$(27)
                        SYSTEM
                END SELECT
            END IF
        LOOP
        PRINT op$
    END IF
LOOP

calculate:
SELECT CASE op$
    CASE "+", "-"
        IF nator_a$ = "" THEN
            nator_a$ = sa$: nator_b$ = sb$
            dator_a$ = "1": dator_b$ = "1"
        ELSE
            nator_b$ = sb$: dator_b$ = "1"
        END IF

        IF INSTR(nator_a$, ".") THEN
            n$ = nator_a$
            GOSUB convert_to_fraction
            nator_a$ = numerator$: dator_a$ = denominator$
        END IF

        IF INSTR(sb$, ".") THEN
            n$ = sb$
            GOSUB convert_to_fraction
            nator_b$ = numerator$: dator_b$ = denominator$
        ELSE
            nator_b$ = sb$: dator_b$ = "1"
        END IF

        ' Cross multiply
        IF dator_a$ <> datorb$ THEN
            stringmatha$ = nator_a$: stringmathb$ = dator_b$: operator$ = "*"
            CALL string_math
            a$ = runningtotal$
            stringmatha$ = dator_a$: stringmathb$ = dator_b$: operator$ = "*"
            CALL string_math
            dator_c$ = runningtotal$ ' Common denominator.

            stringmatha$ = nator_b$: stringmathb$ = dator_a$: operator$ = "*"
            CALL string_math
            b$ = runningtotal$

            stringmatha$ = a$: stringmathb$ = b$: operator$ = op$
            CALL string_math
            nator_c$ = runningtotal$
        END IF

    CASE "*"
        IF nator_a$ = "" THEN
            nator_a$ = sa$: nator_b$ = sb$
            dator_a$ = "1": dator_b$ = "1"
        ELSE
            nator_b$ = sb$: dator_b$ = "1"
        END IF

        IF INSTR(nator_a$, ".") THEN
            n$ = nator_a$
            GOSUB convert_to_fraction
            nator_a$ = numerator$: dator_a$ = denominator$
        END IF

        IF INSTR(sb$, ".") THEN
            n$ = sb$
            GOSUB convert_to_fraction
            nator_b$ = numerator$: dator_b$ = denominator$
        ELSE
            nator_b$ = sb$: dator_b$ = "1"
        END IF

        stringmatha$ = nator_a$: stringmathb$ = nator_b$: operator$ = "*"
        CALL string_math
        nator_c$ = runningtotal$
        stringmatha$ = dator_a$: stringmathb$ = dator_b$: operator$ = "*"
        CALL string_math
        dator_c$ = runningtotal$

    CASE "/"
        IF nator_a$ = "" THEN
            nator_a$ = sa$: nator_b$ = sb$
            dator_a$ = "1": dator_b$ = "1"
        ELSE
            nator_b$ = sb$: dator_b$ = "1"
        END IF

        IF INSTR(nator_a$, ".") THEN
            n$ = nator_a$
            GOSUB convert_to_fraction
            nator_a$ = numerator$: dator_a$ = denominator$
        END IF

        IF INSTR(sb$, ".") THEN
            n$ = sb$
            GOSUB convert_to_fraction
            nator_b$ = numerator$: dator_b$ = denominator$
        ELSE
            nator_b$ = sb$: dator_b$ = "1"
        END IF

        SWAP nator_b$, dator_b$

        stringmatha$ = nator_a$: stringmathb$ = nator_b$: operator$ = "*"
        CALL string_math
        nator_c$ = runningtotal$
        stringmatha$ = dator_a$: stringmathb$ = dator_b$: operator$ = "*"
        CALL string_math
        dator_c$ = runningtotal$

END SELECT

IF betatest% THEN
    PRINT "nator_a$: "; nator_a$
    PRINT "dator_a$: "; dator_a$
    PRINT "nator_b$: "; nator_b$
    PRINT "dator_b$: "; dator_b$
    PRINT "nator_c$: "; nator_c$
    PRINT "dator_c$: "; dator_c$
END IF

a$ = nator_c$: b$ = dator_c$: GOSUB greatest_common_factor
nator_c$ = numerator$: dator_c$ = denominator$

stringmatha$ = nator_c$: stringmathb$ = dator_c$: operator$ = "/"
CALL string_math
sa$ = runningtotal$

COLOR 15, 0: PRINT:
IF LEFT$(sa$, 1) = "-" THEN PRINT "Total: "; sa$ ELSE PRINT "Total:  "; sa$
COLOR 7, 0

nator_a$ = nator_c$
dator_a$ = dator_c$
IF betatest% THEN COLOR 2, 0: PRINT: PRINT "nator_a$ ="; nator_a$, "dator_a$ = "; dator_a$: PRINT: COLOR 7, 0
RETURN

'=================================================================================

convert_to_fraction:
i = 0: j = 0: k = 0: msg$ = ""

IF MID$(n$, 1, 1) = "-" THEN j = 3 ELSE j = 2 ' Look for negative sign.
x1$ = MID$(n$, 1, INSTR(n$, ".") - 1)
IF j = 3 THEN x1$ = MID$(x1$, 2)
x2$ = MID$(n$, INSTR(n$, ".") + 1)
b$ = "1" + STRING$(LEN(x2$), "0")
x1$ = x1$ + x2$
DO UNTIL LEFT$(x1$, 1) <> "0"
    x1$ = MID$(x1$, 2) ' Strip off any leading zeros
LOOP
IF j = 2 THEN a$ = x1$ ELSE a$ = "-" + x1$

z$ = ""

IF betatest% THEN PRINT "numerator and denomintor: "; a$, b$
numerator$ = a$: denominator$ = b$
RETURN

greatest_common_factor:
' GFC algorithm. -------------------------------------------------------------
gfca$ = a$: gfcb$ = b$
IF betatest% THEN PRINT "PRE GFC "; a$; " / "; b$
' Make both numbers positive.
IF MID$(gfca$, 1, 1) = "-" THEN gfca$ = MID$(gfca$, 2)
IF MID$(gfcb$, 1, 1) = "-" THEN gfcb$ = MID$(gfcb$, 2)
' STRING MATH < or > EVAL NOT NEEDED AS NEG NUMBERS ARE CONVERTED TO POS AND NO CHANCE OF 0 AND < 1 > 0 LIKE 0 AND .1 OCCURRING.
IF gfca$ < gfcb$ THEN SWAP gfca$, gfcb$

' MOD operation in string math.
DO
    stringmatha$ = gfca$: stringmathb$ = gfcb$
    operator$ = "/": CALL string_math
    m1$ = runningtotal$
    IF INSTR(m1$, ".") THEN m1$ = MID$(m1$, 1, INSTR(m1$, ".") - 1)
    stringmatha$ = m1$
    stringmathb$ = gfcb$
    operator$ = "*": CALL string_math
    m2$ = runningtotal$
    stringmatha$ = gfca$: stringmathb$ = m2$
    operator$ = "-": CALL string_math
    SWAP gfca$, gfcb$: gfcb$ = runningtotal$
    IF runningtotal$ = "0" THEN EXIT DO
LOOP

stringmatha$ = a$: stringmathb$ = gfca$
operator$ = "/": CALL string_math
numerator$ = runningtotal$
stringmatha$ = b$: stringmathb$ = gfca$
operator$ = "/": CALL string_math
denominator$ = runningtotal$
IF betatest% THEN COLOR 14, 0: PRINT "GFC "; numerator$; " / "; denominator$: COLOR 7, 0
RETURN

'===============================================================================

SUB string_math
    SELECT CASE operator$
        CASE "+", "-"
            GOTO string_add_subtract
        CASE "*"
            GOTO string_multiply
        CASE "/"
            GOTO string_divide
        CASE ELSE
            PRINT "Error, no operator selected. operator$ = "; operator$
    END SELECT

    string_divide:
    divsign% = 0 '''''''''''''''
    divremainder& = 0: divremainder$ = "": divplace& = 0 AND divplace2& = 0: quotient$ = "": divcarry& = 0
    operationdivision% = -1
    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: operationdivision% = 0: EXIT SUB: RETURN '*'
    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: EXIT DO
                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$
            m_product$ = "": GOSUB string_multiply
            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(m_product$) OR LEN(tempcutd$) = LEN(m_product$) AND m_product$ <= tempcutd$ THEN EXIT FOR
        NEXT
        quotient$ = quotient$ + LTRIM$(STR$(div_i%))
        stringmatha$ = LTRIM$(STR$(div_i%)): stringmathb$ = d1divisor$
        m_product$ = "": GOSUB string_multiply
        operator$ = "-"
        stringmatha$ = divremainder$
        stringmathb$ = m_product$
        GOSUB string_add_subtract
        divremainder$ = stringmatha$
        operator$ = "/"
    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
    operationdivision% = 0
    stringmathb$ = quotient$: quotient$ = ""
    '''GOSUB limit_round_convert
    IF stringmathb$ = "overflow" THEN divsign% = 0: operationdivision% = 0: EXIT SUB: RETURN '*'
    '''GOSUB sm_converter
    runningtotal$ = stringmathb$: stringmathb$ = ""
    IF divsign% THEN runningtotal$ = "-" + runningtotal$

    IF stringmathround$ <> "" THEN runningtotal$ = runningtotal$ + stringmathround$
    operationdivision% = 0 '''''
    EXIT SUB ''' or RETURN to select case if goto changed to gosub.

    string_multiply:
    m_decimal_places& = 0: m_product$ = "" ''''''''''''''''''''''
    fac1$ = stringmatha$: fac2$ = stringmathb$ ' Make numbers whole numbers and remove any - sign.
    IF LEFT$(fac1$, 1) = "-" THEN fac1$ = MID$(fac1$, 2): m_sign% = -1
    IF LEFT$(fac2$, 1) = "-" THEN fac2$ = MID$(fac2$, 2): IF m_sign% THEN m_sign% = 0 ELSE m_sign% = -1
    IF INSTR(fac1$, ".") <> 0 THEN m_decimal_places& = LEN(fac1$) - INSTR(fac1$, "."): fac1$ = MID$(fac1$, 1, INSTR(fac1$, ".") - 1) + MID$(fac1$, INSTR(fac1$, ".") + 1)
    IF INSTR(fac2$, ".") <> 0 THEN m_decimal_places& = m_decimal_places& + LEN(fac2$) - INSTR(fac2$, "."): fac2$ = MID$(fac2$, 1, INSTR(fac2$, ".") - 1) + MID$(fac2$, INSTR(fac2$, ".") + 1)
    FOR m_i& = LEN(fac2$) TO 1 STEP -1 ' Multiply each charter top and bottom.
        m_k& = m_l&
        m_x2$ = MID$(fac2$, m_i&, 1)
        FOR m_j& = LEN(fac1$) TO 1 STEP -1
            m_x1$ = MID$(fac1$, m_j&, 1)
            IF m_product$ <> "" THEN
                m_add$ = LTRIM$(STR$(VAL(m_x1$) * VAL(m_x2$))) + STRING$(m_k&, "0")
                m_t& = 0: m_xproduct$ = "": m_carry% = 0
                DO ' Add multiplied characters together.
                    m_x3$ = MID$(m_add$, LEN(m_add$) - m_t&, 1)
                    m_x4$ = MID$(m_product$, LEN(m_product$) - m_t&, 1)
                    IF m_x3$ = "" AND m_x4$ = "" THEN
                        IF m_carry% THEN m_xproduct$ = "1" + m_xproduct$
                        EXIT DO
                    END IF
                    m_g% = VAL(m_x3$) + VAL(m_x4$) + m_carry%
                    IF m_g% >= 10 THEN m_g% = m_g% - 10: m_carry% = 1 ELSE m_carry% = 0
                    m_xproduct$ = LTRIM$(STR$(m_g%)) + m_xproduct$
                    m_t& = m_t& + 1
                LOOP
                m_product$ = m_xproduct$: m_xproduct$ = ""
            ELSE
                m_product$ = LTRIM$(STR$(VAL(m_x1$) * VAL(m_x2$))) + STRING$(m_k&, "0") ' First loop makes variable here.
            END IF
            m_k& = m_k& + 1 ' Adds trailing zeros multiplication
        NEXT
        m_l& = m_l& + 1 ' Used to reset value for m_k& adding one trailing zer for each loop.
    NEXT
    fac1$ = "": fac2$ = "": m_l& = 0: m_k& = 0: m_t& = 0
    IF m_decimal_places& > LEN(m_product$) THEN m_product$ = STRING$(m_decimal_places& - LEN(m_product$), "0") + m_product$ ' Add any leading zeros to a decimal. Ex: .02 * .01 is factored as 002. It needs one leading zero before adding the decimal point, .0002.
    IF m_decimal_places& AND m_product$ <> "0" THEN ' Replace any decimal point.
        m_product$ = MID$(m_product$, 1, LEN(m_product$) - m_decimal_places&) + "." + MID$(m_product$, LEN(m_product$) - m_decimal_places& + 1)
    END IF
    DO UNTIL LEFT$(m_product$, 1) <> "0" ' Remove leading zeros.
        m_product$ = MID$(m_product$, 2)
    LOOP
    IF m_decimal_places& THEN
        DO UNTIL RIGHT$(m_product$, 1) <> "0" ' Remove trailing zeros in a decimal sum.
            m_product$ = MID$(m_product$, 1, LEN(m_product$) - 1)
        LOOP
    END IF
    IF m_product$ = "" THEN m_product$ = "0": m_sign% = 0
    IF RIGHT$(m_product$, 1) = "." THEN m_product$ = MID$(m_product$, 1, LEN(m_product$) - 1) ' Remove decimal from the end of an integer total.
    IF operationdivision% THEN m_sign% = 0: RETURN
    stringmathb$ = m_product$: m_product$ = ""
    '''GOSUB limit_round_convert
    IF stringmathb$ = "overflow" THEN EXIT SUB: RETURN '*'
    '''GOSUB sm_converter
    runningtotal$ = stringmathb$: stringmathb$ = ""
    IF m_sign% THEN runningtotal$ = "-" + runningtotal$: m_sign% = 0
    EXIT SUB ''' or RETURN to select case if goto changed to gosub.

    string_add_subtract:
    IF INSTR(stringmatha$, ".") <> 0 THEN ' Evaluate sum for decimal fraction.
        sumplace& = LEN(stringmatha$) - INSTR(stringmatha$, ".")
        stringmatha$ = MID$(stringmatha$, 1, INSTR(stringmatha$, ".") - 1) + MID$(stringmatha$, INSTR(stringmatha$, ".") + 1) ' Strip out decimal
    END IF
    IF INSTR(stringmathb$, ".") <> 0 THEN ' Evaluate number for decimal fraction.
        numplace& = LEN(stringmathb$) - INSTR(stringmathb$, ".")
        stringmathb$ = MID$(stringmathb$, 1, INSTR(stringmathb$, ".") - 1) + MID$(stringmathb$, INSTR(stringmathb$, ".") + 1) ' Strip out decimal
    END IF
    IF sumplace& > numplace& THEN addsubplace& = sumplace& ELSE addsubplace& = numplace&
    IF sumplace& > addsubplace& THEN
        stringmatha$ = stringmatha$ + STRING$(sumplace& - addsubplace&, "0")
    ELSEIF addsubplace& > sumplace& THEN
        stringmatha$ = stringmatha$ + STRING$(addsubplace& - sumplace&, "0")
    END IF
    IF numplace& > addsubplace& THEN
        stringmathb$ = stringmathb$ + STRING$(numplace& - addsubplace&, "0")
    ELSEIF addsubplace& > numplace& THEN
        stringmathb$ = stringmathb$ + STRING$(addsubplace& - numplace&, "0")
    END IF ' END Decimal evaluations.

    IF LEFT$(stringmatha$, 1) = "-" THEN sign_input$ = "-" ELSE sign_input$ = "+"
    IF LEFT$(stringmathb$, 1) = "-" THEN sign_total$ = "-" ELSE sign_total$ = "+"

    addsubsign% = 0
    SELECT CASE sign_input$ + operator$ + sign_total$
        CASE "+++", "+--"
            operator$ = "+"
            IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
        CASE "++-", "+-+"
            operator$ = "-"
            IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
            IF VAL(stringmathb$) > VAL(stringmatha$) THEN SWAP stringmatha$, stringmathb$: addsubsign% = -1
        CASE "---", "-++"
            operator$ = "-"
            IF LEFT$(stringmatha$, 1) = "-" THEN stringmatha$ = MID$(stringmatha$, 2)
            IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
            IF VAL(stringmathb$) > VAL(stringmatha$) THEN SWAP stringmatha$, stringmathb$ ELSE addsubsign% = -1
        CASE "--+", "-+-"
            operator$ = "+"
            IF LEFT$(stringmatha$, 1) = "-" THEN stringmatha$ = MID$(stringmatha$, 2)
            IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
            addsubsign% = -1
    END SELECT

    IF LEN(stringmatha$) > LEN(stringmathb$) THEN
        stringmathb$ = STRING$(LEN(stringmatha$) - LEN(stringmathb$), "0") + stringmathb$
    ELSEIF LEN(stringmatha$) < LEN(stringmathb$) THEN
        stringmatha$ = STRING$(LEN(stringmathb$) - LEN(stringmatha$), "0") + stringmatha$
    END IF
    addsubx1$ = ""

    SELECT CASE operator$
        CASE "+", "="
            FOR addsubii& = LEN(stringmatha$) TO 1 STEP -1
                addsubx1% = VAL(MID$(stringmatha$, addsubii&, 1)) + VAL(MID$(stringmathb$, addsubii&, 1)) + addsubcarry%
                IF addsubx1% > 9 THEN addsubx1% = addsubx1% - 10: addsubcarry% = 1 ELSE addsubcarry% = 0
                addsubx1$ = LTRIM$(STR$(addsubx1%)) + addsubx1$
            NEXT
            IF addsubcarry% THEN addsubx1$ = "1" + addsubx1$: addsubcarry% = 0
            GOSUB replace_decimal
        CASE "-"
            FOR addsubii& = LEN(stringmatha$) TO 1 STEP -1
                addsubx1% = VAL(MID$(stringmatha$, addsubii&, 1)) - VAL(MID$(stringmathb$, addsubii&, 1)) + addsubcarry%
                IF addsubx1% < 0 THEN addsubx1% = addsubx1% + 10: addsubcarry% = -1 ELSE addsubcarry% = 0
                addsubx1$ = LTRIM$(STR$(addsubx1%)) + addsubx1$
            NEXT
            IF addsubx1$ <> "" AND addsubx1$ <> STRING$(LEN(addsubx1$), "0") THEN GOSUB replace_decimal
            DO UNTIL LEFT$(addsubx1$, 1) <> "0" ' Remove leading zeros.
                addsubx1$ = MID$(addsubx1$, 2)
            LOOP
            IF addsubx1$ = "" THEN
                addsubx1$ = "0": addsubsign% = 0
            ELSE
                IF addsubcarry% THEN addsubx1$ = "-" + addsubx1$: addsubcarry% = 0
            END IF
    END SELECT

    IF addsubsign% THEN
        IF LEFT$(addsubx1$, 1) = "-" THEN addsubx1$ = MID$(addsubx1$, 2) ELSE addsubx1$ = "-" + addsubx1$
    END IF
    stringmatha$ = addsubx1$: addsubx1$ = ""
    IF operationdivision% THEN RETURN
    stringmathb$ = stringmatha$: stringmatha$ = ""
    IF LEFT$(stringmathb$, 1) = "-" THEN
        stringmathb$ = MID$(stringmathb$, 2)
        n2sign$ = "-"
    ELSE
        n2sign$ = ""
    END IF
    ''' GOSUB limit_round_convert
    IF stringmathb$ = "overflow" THEN n2sign$ = "": EXIT SUB: RETURN '*'
    ''' GOSUB sm_converter
    runningtotal$ = n2sign$ + stringmathb$: n2sign$ = ""
    EXIT SUB ''' or RETURN to select case if goto changed to gosub.

    replace_decimal:
    IF addsubplace& THEN
        addsubx1$ = STRING$(addsubplace& - LEN(addsubx1$), "0") + addsubx1$
        addsubx1$ = MID$(addsubx1$, 1, LEN(addsubx1$) - addsubplace&) + "." + MID$(addsubx1$, LEN(addsubx1$) - addsubplace& + 1)
        DO UNTIL RIGHT$(addsubx1$, 1) <> "0" ' Remove trailing zeros in a decimal sum.
            addsubx1$ = MID$(addsubx1$, 1, LEN(addsubx1$) - 1)
            addsubplace& = addsubplace& - 1
        LOOP
        IF RIGHT$(addsubx1$, 1) = "." THEN addsubx1$ = MID$(addsubx1$, 1, LEN(addsubx1$) - 1) ' Number is now an integer.
    END IF
    RETURN
END SUB


Pete
Reply


Messages In This Thread
Perpetual string math calculator. - by Pete - 08-10-2022, 05:11 PM
RE: Perpetual string math calculator. - by Pete - 08-11-2022, 03:24 AM
RE: Perpetual string math calculator. - by Pete - 08-11-2022, 12:39 PM
RE: Perpetual string math calculator. - by Pete - 08-11-2022, 08:29 PM
RE: Perpetual string math calculator. - by Pete - 08-11-2022, 10:08 PM
RE: Perpetual string math calculator. - by bplus - 08-11-2022, 10:07 PM
RE: Perpetual string math calculator. - by Jack - 08-11-2022, 10:35 PM
RE: Perpetual string math calculator. - by Pete - 08-11-2022, 11:35 PM
RE: Perpetual string math calculator. - by Jack - 08-11-2022, 11:42 PM
RE: Perpetual string math calculator. - by Pete - 08-11-2022, 11:51 PM
RE: Perpetual string math calculator. - by Pete - 08-12-2022, 01:56 AM



Users browsing this thread: 16 Guest(s)