Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Faster addition in string math. Now with multiplication!
#21
not bad Pete, 6 second here
Reply
#22
@Jack

6 seconds for 5000 iterations? I mean I know I bought my computer used from a guy named F. Flintstone, but I wouldn't have thought the difference would b that great. on faster systems. I figured most of you guys would be able to run 5000 loops in around 15 - 20 seconds.

Pete
Reply
#23
12.5 seconds on my laptop, unless I got my timer in the wrong place to compare with you guys.

Code: (Select All)
Width 160, 42
_ScreenMove 0, 0
Do
    limit&& = 5000
    'betatest% = -1
    If betatest% Then limit&& = 16

    Do
        Input "Number: "; x$: Print

        If x$ = "" Then System

        If Left$(x$, 1) = "-" Then
            Print "Negatives not allowed. Redo..": _Delay 2: Print
        Else
            validate_string x$
            If InStr(x$, "invalid") = 0 Then Exit Do
            Print "Sorry, "; x$: _Delay 1: Print
        End If
    Loop

    x# = Val(x$) ' Needed for QB64 SQR() comparison only.
    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

    timed## = Timer
    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

    Print

    If dp&& Then
        sqrt$ = Mid$(sqrt$, 0, dp&& + 1) + "." + Mid$(sqrt$, dp&& + 1)
    End If

    _Clipboard$ = sqrt$
    Print "QB64 SQR:"; Sqr(x#)
    Print "Pete SQR: "; sqrt$: _Delay 1
    Print
    Print Using "###.##### seconds"; Timer - timed##
    Clear
4 Loop

Sub string_math (stringmatha$, operator$, stringmathb$, runningtotal$, terminating_decimal%, limit&&)
    Dim As _Integer64 a, b, c, aa, bb, cc, s, ss
    a1$ = stringmatha$: b1$ = stringmathb$

    Select Case operator$
        Case "+", "-"
            GoTo string_add_subtract_new
        Case "*"
            GoTo string_multiply_new
        Case "/"
            GoTo string_divide
        Case Else
            Print "Error, no operator selected. operator$ = "; operator$
    End Select

    string_divide:
    terminating_decimal% = 0: divsign% = 0: divremainder& = 0: divremainder$ = "": divplace& = 0: 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
    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$
            m_product$ = "": GoSub string_multiply_new
            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_new
        operator$ = "-"
        stringmatha$ = divremainder$
        stringmathb$ = m_product$
        GoSub string_add_subtract_new
        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$ = ""

    If stringmathb$ = "overflow" Then divsign% = 0: operationdivision% = 0: Exit Sub

    runningtotal$ = stringmathb$: stringmathb$ = ""
    If divsign% Then runningtotal$ = "-" + runningtotal$

    If stringmathround$ <> "" Then runningtotal$ = runningtotal$ + stringmathround$
    operationdivision% = 0
    Exit Sub

    '------------------------------------------------------------------------
    string_add_subtract_new:
    s = 18

    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

    s = 18: z$ = ""

    Do
        i&& = i&& + s
        x1$ = Mid$(a$, Len(a$) - i&& + 1, s)
        x2$ = Mid$(b$, Len(b$) - i&& + 1, s)
        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$(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
    Exit Sub

    '------------------------------------------------------------------------
    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

    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
            If betatest% Then Print "x1$ = "; x1$;: Locate , 20: Print "x2$ = "; x2$;: Locate , 35: Print Val(x1$) * Val(x2$) + c;: Locate , 55: Print "c = "; c;: Locate , 75: Print "val = "; a,
            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 betatest% Then Locate , 100: Print a;: Locate , 120: Print 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")
            If betatest% Then Print "aa$ "; aa$; " + bb$ "; z$;: Color 14, 0: Print String$(jj&& - 1, "0"); " = ";: Color 7, 0: Sleep
            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$
            If betatest% Then Color 2, 0: Print holdaa$: Color 7, 0
        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$

    Exit Sub

    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

    string_comp:
    Do
        ' Remove trailing zeros after a decimal point.
        If InStr(acomp$, ".") Then
            Do Until Right$(acomp$, 1) <> "0" And Right$(acomp$, 1) <> "." And Right$(acomp$, 1) <> "-"
                acomp$ = Mid$(acomp$, 1, Len(acomp$) - 1)
            Loop
        End If
        If InStr(bcomp$, ".") Then
            Do Until Right$(bcomp$, 1) <> "0" And Right$(bcomp$, 1) <> "." And Right$(bcomp$, 1) <> "-"
                bcomp$ = Mid$(bcomp$, 1, Len(bcomp$) - 1)
            Loop
        End If

        If Mid$(acomp$, 1, 2) = "-0" Or acomp$ = "" Or acomp$ = "-" Then acomp$ = "0"
        If Mid$(bcomp$, 1, 2) = "-0" Or bcomp$ = "" Or bcomp$ = "-" Then bcomp$ = "0"

        ' A - and +
        If Left$(acomp$, 1) = "-" Then j% = -1
        If Left$(bcomp$, 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(acomp$, ".")
        k% = InStr(bcomp$, ".")
        If j% = 0 And k% Then
            If acomp$ = "0" Then gl% = -1 Else gl% = 1
            Exit Do
        End If
        If k% = 0 And j% Then
            If bcomp$ = "0" Then gl% = 1 Else gl% = -1
            Exit Do
        End If

        ' Both decimals.
        If j% Then
            If acomp$ > bcomp$ Then
                gl% = 1
            ElseIf acomp$ = bcomp$ Then gl% = 0
            ElseIf acomp$ < bcomp$ Then gl% = -1
            End If
            Exit Do
        End If

        ' Both positive or both negative whole numbers.
        Select Case Len(acomp$)
            Case Is < Len(bcomp$)
                gl% = -1
            Case Is = Len(bcomp$)
                If acomp$ = bcomp$ Then
                    gl% = 0
                ElseIf acomp$ > bcomp$ Then gl% = 1
                ElseIf acomp$ < bcomp$ Then gl% = -1
                End If
            Case Is > Len(bcomp$)
                gl% = 1
        End Select
        Exit Do
    Loop
    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: Print "1*": Exit Do
        If j% = 0 And k% Then gl% = 1: Print "2*": 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: Print "4*" Else gl% = 1: Print "5*"
            Exit Do
        End If
        If k% = 0 And j% Then
            If compb$ = "0" Then gl% = 1: Print "6*" Else gl% = -1: Print "7*"
            Exit Do
        End If

        ' Both decimals.
        If j% Then
            If compa$ > compb$ Then
                gl% = 1: Print "8*"
            ElseIf compa$ = compb$ Then gl% = 0: Print "9*"
            ElseIf compa$ < compb$ Then gl% = -1: Print "10*"
            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

Sub validate_string (stringmathb$)
    Do ' Faux loop.
        vsn_negcnt& = 0: vsn_poscnt& = 0: vsn_depresent& = 0: decimalcnt& = 0: vsn_numberpresent& = 0: vsn_zerospresent& = 0
        If Left$(stringmathb$, 1) = "-" Then stringmathb$ = Mid$(stringmathb$, 2): sm_sign$ = "-" Else sm_sign$ = ""
        If Left$(stringmathb$, 1) = "+" Then If sm_sign$ <> "-" Then stringmathb$ = Mid$(stringmathb$, 2) Else stringmathb$ = "invalid number": Exit Do
        If InStr(UCase$(stringmathb$), "D") Or InStr(UCase$(stringmathb$), "E") Then ' Evaluate for Scientific Notation.
            For sm_i& = 1 To Len(stringmathb$)
                validatenum$ = Mid$(UCase$(stringmathb$), sm_i&, 1)
                Select Case validatenum$
                    Case "+"
                        If vsn_depresent& Then vsn_poscnt& = vsn_poscnt& + 1 Else stringmathb$ = "invalid number": Exit Do
                    Case "-"
                        If vsn_depresent& Then vsn_negcnt& = vsn_negcnt& + 1 Else stringmathb$ = "invalid number": Exit Do
                    Case "0" To "9"
                        vsn_numberpresent& = -1
                    Case "D", "E"
                        vsn_depresent& = vsn_depresent& + 1
                        If decimalcnt& = 0 And sm_i& <> 2 Or vsn_depresent& > 1 Or vsn_numberpresent& = 0 Or vsn_negcnt& > 1 Or vsn_poscnt& > 1 Or vsn_negcnt& = 1 And vsn_poscnt& >= 1 Then vsn_numberpresent& = 0: Exit For
                        vsn_numberpresent& = 0
                        Mid$(stringmathb$, sm_i&, 1) = "e" ' Standardize
                    Case "."
                        decimalcnt& = decimalcnt& + 1
                        If sm_i& <> 2 Then vsn_numberpresent& = 0: Exit For
                    Case Else
                        vsn_numberpresent& = 0: Exit For
                End Select
            Next
            If decimalcnt& = 0 Then stringmathb$ = Mid$(stringmathb$, 1, 1) + "." + Mid$(stringmathb$, 2) ' Standardize "."
            If vsn_numberpresent& = 0 Or vsn_negcnt& = 1 And vsn_poscnt& = 1 Or decimalcnt& > 1 Or InStr(stringmathb$, ".") <> 2 Then stringmathb$ = "invalid number": Exit Do
            vsn_depresent& = InStr(stringmathb$, "e")
            sm_x$ = Mid$(stringmathb$, vsn_depresent& + 1, 1) ' Standardize exponent "+" these two lines.
            If sm_x$ <> "+" And sm_x$ <> "-" Then stringmathb$ = Mid$(stringmathb$, 1, vsn_depresent&) + "+" + Mid$(stringmathb$, vsn_depresent& + 1)
            If Mid$(stringmathb$, vsn_depresent& + 2, 1) = "0" Then
                If Mid$(stringmathb$, vsn_depresent& + 3, 1) <> "" Then stringmathb$ = "invalid number": Exit Do ' No leading zeros allowed in exponent notation.
            End If
            jjed& = InStr(stringmathb$, "e") ' Get position of notation.
            valexpside$ = Mid$(stringmathb$, jjed&) ' These two lines break up into number and notation
            stringmathb$ = Mid$(stringmathb$, 1, jjed& - 1) ' stringmathb$ is +- single digit whole number, decimal point and decimal number. valexpside$ is notation, sign and exponent.
            Do Until Right$(stringmathb$, 1) <> "0" ' Remove any trailing zeros for number. Example 1.0d3 or 1.0000d3, etc.
                stringmathb$ = Mid$(stringmathb$, 1, Len(stringmathb$) - 1)
            Loop
            If Val(Mid$(stringmathb$, 1, InStr(stringmathb$, ".") - 1)) = 0 Then
                If Right$(stringmathb$, 1) = "." Then
                    stringmathb$ = "0.e+0" ' Handles all types of zero entries.
                Else
                    stringmathb$ = "invalid number": Exit Do
                End If
                Exit Do
            End If
            stringmathb$ = sm_sign$ + stringmathb$ + valexpside$
            Exit Do
        Else
            For sm_i& = 1 To Len(stringmathb$)
                validatenum$ = Mid$(stringmathb$, sm_i&, 1)
                Select Case validatenum$
                    Case "."
                        decimalcnt& = decimalcnt& + 1
                    Case "0"
                        vsn_zerospresent& = -1
                    Case "1" To "9"
                        vsn_numberpresent& = -1
                    Case "$"
                    Case Else
                        stringmathb$ = "invalid number": Exit Do
                End Select
            Next
            If decimalcnt& > 1 Or vsn_negcnt& > 1 Or vsn_poscnt& > 1 Or vsn_negcnt& >= 1 And vsn_poscnt& >= 1 Then
                stringmathb$ = "invalid number": Exit Do
            End If

            Rem IF INSTR(stringmathb$, "$") THEN GOSUB currency_validate
            Rem IF INSTR(stringmathb$, ",") THEN
            Rem GOSUB comma_validation
            Rem IF stringmathb$ = "invalid number" THEN exit do
            Rem GOSUB comma_removal
            Rem END IF

            If Right$(stringmathb$, 1) = "." Then stringmathb$ = Mid$(stringmathb$, 1, Len(stringmathb$) - 1)
            Do Until Left$(stringmathb$, 1) <> "0" ' Strip off any leading zeros.
                stringmathb$ = Mid$(stringmathb$, 2)
            Loop
            stringmathb$ = sm_sign$ + stringmathb$
            If InStr(stringmathb$, ".") Then
                Do Until Right$(stringmathb$, 1) <> "0" ' Strip off any trailing zeros in a decimal.
                    stringmathb$ = Mid$(stringmathb$, 1, Len(stringmathb$) - 1)
                Loop
            End If
            If Right$(stringmathb$, 1) = "." Then stringmathb$ = Mid$(stringmathb$, 1, Len(stringmathb$) - 1)
            If vsn_numberpresent& = 0 Then
                If vsn_zerospresent& Then
                    stringmathb$ = "0"
                Else
                    stringmathb$ = "invalid number"
                End If
            End If
        End If
        Exit Do
    Loop
End Sub
Reply
#24
Now working with pi and found one more bug, which didn't affect all of the sqrt calcs, amazingly enough.

Before the DO:LOOP that uses the counter h&& = h&& + s begins, I added...

IF LEN(a$) < LEN(b$) THEN SWAP a$, b$

The loop takes care of some calculation where the VAL() drops leading zeros, but to do so properly, the fist variable a$ of a$ and b$ variables, must always be the longest string, or at lease equal in length for that leading zero conversion from VAL() to STR() to work properly.

I have edited the last post with this statement addition.

It looks like I lost a couple of seconds in the process. Oh well, fast and accurate beats faster and wrong.

Pete
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Determining if variable or static string is passed to a Sub dano 9 1,225 06-20-2025, 06:31 PM
Last Post: CookieOscar
  Most efficient way to build a big variable length string? mdijkens 9 1,893 01-17-2025, 11:36 PM
Last Post: ahenry3068
  Math and Physics stuff SMcNeill 1 534 05-28-2024, 06:25 PM
Last Post: Pete
  The IDE Math Evaluator in Tools TerryRitchie 2 778 05-07-2024, 10:24 PM
Last Post: TerryRitchie
  REDIM, TYPE, and STRING Woes TerryRitchie 16 3,154 04-13-2023, 05:17 AM
Last Post: DSMan195276

Forum Jump:


Users browsing this thread: