Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
need a Scientific Notation to real number converter
#1
Hi all
Need help with a Scientific Notation to real number converter.   Below is a mockup for testing the Function but if I do the
calculations by hand the outputs don't match.  

Thanks in advance

R1

Code: (Select All)

FOR L1 = 1 TO 9
    IF L1 = 1 THEN A = 75 / 130
    IF L1 = 2 THEN A =  1 / 103
    IF L1 = 3 THEN A =  7 / 27
    IF L1 = 4 THEN A = 11 / 42
    IF L1 = 5 THEN A = 15 / 63
    IF L1 = 6 THEN A = 35 / 118
    IF L1 = 7 THEN A = 60 / 142
    IF L1 = 8 THEN A = 47 / 125
    IF L1 = 9 THEN A = 93 / 148

    A=A^2
    A$ = StrNum$(A)
    A$=MID$(A$,1,6)
    P=P + VAL(A$)

    PRINT A$
NEXT

P = (P/9)
A$ = STRNUM$(P)
A$=MID$(A$,1,6)
PRINT A$ + " <- averaged"
color 10
print "Press any key"
SLEEP
SYSTEM

FUNCTION StrNum$ (n)
    value$ = UCASE$(LTRIM$(STR$(n)))
    XPOS1 = INSTR(value$, "D") + INSTR(value$, "E")
    IF XPOS1 THEN
        expo = VAL(MID$(value$, XPOS1 + 1))
        IF VAL(value$) < 0 THEN
            sign$ = "-": value$ = MID$(value$, 2, XPOS1 - 2)
        ELSE value$ = MID$(value$, 1, XPOS1 - 1)
        END IF
        dot = INSTR(value$, "."): L = LEN(value$)
        IF expo > 0 THEN ADD$ = StrNum$(expo - (L - dot), "0")
        IF expo < 0 THEN min$ = StrNum$(ABS(expo) - (dot - 1), "0"): DP$ = "."
        FOR N = 1 TO L
            IF MID$(value$, N, 1) <> "." THEN num$ = num$ + MID$(value$, N, 1)
        NEXT
    ELSE StrNum$ = value$: EXIT FUNCTION
    END IF
    StrNum$ = sign$ + DP$ + min$ + num$ + ADD$
END FUNCTION
Reply
#2
Code: (Select All)
Screen _NewImage(1280, 720, 32)
Limit = 10000
Print "Fib"; Limit; "="
last2$ = "0"
last$ = "1"
time## = Timer
For i = 1 To Limit - 2
    result$ = StringAdd(last$, last2$)
    last2$ = last$
    last$ = result$
Next
Print result$
Print Using "###.### seconds to run."; Timer - time##

End

Function StringAdd$ (tempa$, tempb$)
    a$ = tempa$: b$ = tempb$ 'don't alter our original numbers
    Dim As _Unsigned _Integer64 a, b, c, carryover 'to hold our values

    'first fix the numbers to notmalize their lengths
    FixNumbers a$, b$
    'find the signs and strip them off
    If Left$(a$, 1) = "-" Then sa$ = "-": a$ = Mid$(a$, 2) Else sa$ = " "
    If Left$(b$, 1) = "-" Then sb$ = "-": b$ = Mid$(b$, 2) Else sb$ = " "
    'find the decimal position
    dp = InStr(a$, ".")
    If dp > 0 Then 'remove the decimal place from our numbers.  We can put it back later, in its proper position
        righta$ = Mid$(a$, dp + 1)
        rightb$ = Mid$(b$, dp + 1)
        a$ = Left$(a$, dp - 1) + righta$
        b$ = Left$(b$, dp - 1) + rightb$
    End If
    'our strings are now nothing but numbers with no signs and no decimals to deal with.  Let's start adding!
    'are we adding or really subtracting?

    If sa$ <> sb$ Then 'we're subtracting the two values if the signs aren't the same.
        Select Case a$
            Case Is < b$: s$ = sb$: Swap a$, b$ 'our sign is going to be determiined by b$
            Case Is = b$ 'if the two values are the same and are subtracting, our result is zero!
                StringAdd$ = "0" 'How easy was that?
                Exit Function
            Case Else: s$ = sa$ 'our sign is determined by a$
        End Select
        Do
            lb = Len(b$)
            a = Val(Right$(a$, 18)): a$ = Left$(a$, Len(a$) - 18)
            b = Val(Right$(b$, 18)): b$ = Left$(b$, Len(b$) - 18)
            If borrow Then b = b + 1~&& 'in case we had to borrow a digit for the last subtraction
            If a < b Then
                If lb < 18 Then a = a + 10 ^ lb Else a = a + 10 ^ 18
                borrow = -1
            Else
                borrow = 0
            End If
            c = a - b
            temp$ = _Trim$(Str$(c))
            answer$ = String$(18 - Len(temp$), "0") + temp$ + answer$
        Loop Until Len(a$) = 0
        'remove leading 0's
        Do Until Left$(answer$, 1) <> "0"
            answer$ = Mid$(answer$, 2)
        Loop
        'remember to add in the decimal place before finished
        dp = Len(righta$)
        If dp > 0 Then
            answer$ = Left$(answer$, Len(answer$) - dp) + "." + Right$(answer$, dp)
        End If
        StringAdd$ = s$ + answer$
        Exit Function
    End If

    Do
        a1$ = Right$(a$, 18)
        b1$ = Right$(b$, 18)
        a = Val(Right$(a$, 18)): a$ = Left$(a$, Len(a$) - 18)
        b = Val(Right$(b$, 18)): b$ = Left$(b$, Len(b$) - 18)
        c = a + b + carryover
        temp$ = _Trim$(Str$(c))
        If Len(temp$) > 18 Then 'see if we have an answer that is more than 18 digits
            temp$ = Right$(temp$, 18) 'keep 18 digits
            carryover = 1 'store one for carry over
        Else
            carryover = 0 'no carryover
        End If
        answer$ = String$(18 - Len(temp$), "0") + temp$ + answer$
    Loop Until Len(a$) = 0
    If carryover Then answer$ = "1" + answer$
    'remember to add in the decimal place before finished
    dp = Len(righta$)
    If dp > 0 Then
        answer$ = Left$(answer$, Len(answer$) - dp) + "." + Right$(answer$, dp)
    End If
    'remove leading 0's
    Do Until Left$(answer$, 1) <> "0"
        answer$ = Mid$(answer$, 2)
    Loop
    StringAdd$ = sa$ + answer$
End Function

Function StringSubtract$ (tempa$, tempb$)
    a$ = tempa$: b$ = tempb$
    FixNumbers a$, b$
    If Left$(b$, 1) = "-" Then b$ = Mid$(b$, 2) Else b$ = "-" + b$
    StringSubtract$ = StringAdd$(a$, b$)
End Function


Sub FixNumbers (a$, b$)
    'first remove scientific notation and spaces from both
    a$ = _Trim$(N2S$(a$)): b$ = _Trim$(N2S$(b$))
    'then find the decimal position for both and normalize the expressions
    d1 = InStr(a$, "."): d2 = InStr(b$, ".")
    If d1 <> 0 Then 'break down the left and right side of the decimal point for ease of processing  (this is a$)
        lefta$ = Left$(a$, d1 - 1)
        righta$ = Mid$(a$, d1)
    Else
        lefta$ = a$
    End If
    If d2 <> 0 Then 'break down the left and right side of the decimal point for ease of processing  (this is b$)
        leftb$ = Left$(b$, d2 - 1)
        rightb$ = Mid$(b$, d2)
    Else
        leftb$ = b$
    End If

    'normalize the right side of our expressions
    l1 = Len(righta$): l2 = Len(rightb$)
    If l1 < l2 Then
        addzero = l2 - l1
        If l1 = 0 Then righta$ = ".": addzero = addzero - 1
        righta$ = righta$ + String$(addzero, "0")
    ElseIf l1 > l2 Then
        addzero = l1 - l2
        'If l2 = 0 Then rightb$ = ".": addzero = addzero - 1
        rightb$ = rightb$ + String$(addzero, "0")
    End If



    'strip off any plus/minus signs from the two numbers.
    If Left$(lefta$, 1) = "-" Then signa$ = "-": lefta$ = Mid$(lefta$, 2)
    If Left$(leftb$, 1) = "-" Then signb$ = "-": leftb$ = Mid$(leftb$, 2)
    If Left$(lefta$, 1) = "+" Then signa$ = "": lefta$ = Mid$(lefta$, 2)
    If Left$(leftb$, 1) = "+" Then signb$ = "": leftb$ = Mid$(leftb$, 2)
    'normalize the left side of our expressions
    l1 = Len(lefta$): l2 = Len(leftb$)
    If l1 < l2 Then
        addzero = l2 - l1
        lefta$ = String$(addzero, "0") + lefta$
    ElseIf l1 > l2 Then
        addzero = l1 - l2
        leftb$ = String$(addzero, "0") + leftb$
    End If
    'and then put it all together
    a$ = signa$ + lefta$ + righta$
    b$ = signb$ + leftb$ + rightb$
End Sub





Function N2S$ (exp$) 'scientific Notation to String

    t$ = LTrim$(RTrim$(exp$))
    If Left$(t$, 1) = "-" Or Left$(t$, 1) = "N" Then sign$ = "-": t$ = Mid$(t$, 2)

    dp = InStr(t$, "D+"): dm = InStr(t$, "D-")
    ep = InStr(t$, "E+"): em = InStr(t$, "E-")
    check1 = Sgn(dp) + Sgn(dm) + Sgn(ep) + Sgn(em)
    If check1 < 1 Or check1 > 1 Then N2S = exp$: Exit Function 'If no scientic notation is found, or if we find more than 1 type, it's not SN!

    Select Case l 'l now tells us where the SN starts at.
        Case Is < dp: l = dp
        Case Is < dm: l = dm
        Case Is < ep: l = ep
        Case Is < em: l = em
    End Select

    l$ = Left$(t$, l - 1) 'The left of the SN
    r$ = Mid$(t$, l + 1): r&& = Val(r$) 'The right of the SN, turned into a workable long


    If InStr(l$, ".") Then 'Location of the decimal, if any
        If r&& > 0 Then
            r&& = r&& - Len(l$) + 2
        Else
            r&& = r&& + 1
        End If
        l$ = Left$(l$, 1) + Mid$(l$, 3)
    End If

    Select Case r&&
        Case 0 'what the heck? We solved it already?
            'l$ = l$
        Case Is < 0
            For i = 1 To -r&&
                l$ = "0" + l$
            Next
            l$ = "0." + l$
        Case Else
            For i = 1 To r&&
                l$ = l$ + "0"
            Next
    End Select

    N2S$ = sign$ + l$
End Function


Function DWD$ (exp$) 'Deal With Duplicates
    'To deal with duplicate operators in our code.
    'Such as --  becomes a +
    '++ becomes a +
    '+- becomes a -
    '-+ becomes a -
    t$ = exp$
    Do
        bad = 0
        Do
            l = InStr(t$, "++")
            If l Then t$ = Left$(t$, l - 1) + "+" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
        Do
            l = InStr(t$, "+-")
            If l Then t$ = Left$(t$, l - 1) + "-" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
        Do
            l = InStr(t$, "-+")
            If l Then t$ = Left$(t$, l - 1) + "-" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
        Do
            l = InStr(t$, "--")
            If l Then t$ = Left$(t$, l - 1) + "+" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
    Loop Until Not bad
    DWD$ = t$
End Function

N2S$ is the function you want.
Reply
#3
(10-09-2023, 06:15 AM)random1 Wrote: Hi all
Need help with a Scientific Notation to real number converter.   Below is a mockup for testing the Function but if I do the
calculations by hand the outputs don't match.  

Thanks in advance
Maybe I'm missing the point, but here's a simple method I wrote some time back:

Input "Enter your scientific notation number"; sn$
sn$ = UCase$(sn$)
p = InStr(sn$, "E")
lft = Val(Left$(sn$, p - 1))
rt = Val(Right$(sn$, Len(sn$) - p))
Print lft, rt
dn = lft * 10 ^ rt
Print dn
Sleep
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Please visit my Website at: http://oldendayskids.blogspot.com/
Reply
#4
(10-09-2023, 07:07 AM)SMcNeill Wrote:
Code: (Select All)
Screen _NewImage(1280, 720, 32)
Limit = 10000
Print "Fib"; Limit; "="
last2$ = "0"
last$ = "1"
time## = Timer
For i = 1 To Limit - 2
    result$ = StringAdd(last$, last2$)
    last2$ = last$
    last$ = result$
Next
Print result$
Print Using "###.### seconds to run."; Timer - time##

End

Function StringAdd$ (tempa$, tempb$)
    a$ = tempa$: b$ = tempb$ 'don't alter our original numbers
    Dim As _Unsigned _Integer64 a, b, c, carryover 'to hold our values

    'first fix the numbers to notmalize their lengths
    FixNumbers a$, b$
    'find the signs and strip them off
    If Left$(a$, 1) = "-" Then sa$ = "-": a$ = Mid$(a$, 2) Else sa$ = " "
    If Left$(b$, 1) = "-" Then sb$ = "-": b$ = Mid$(b$, 2) Else sb$ = " "
    'find the decimal position
    dp = InStr(a$, ".")
    If dp > 0 Then 'remove the decimal place from our numbers.  We can put it back later, in its proper position
        righta$ = Mid$(a$, dp + 1)
        rightb$ = Mid$(b$, dp + 1)
        a$ = Left$(a$, dp - 1) + righta$
        b$ = Left$(b$, dp - 1) + rightb$
    End If
    'our strings are now nothing but numbers with no signs and no decimals to deal with.  Let's start adding!
    'are we adding or really subtracting?

    If sa$ <> sb$ Then 'we're subtracting the two values if the signs aren't the same.
        Select Case a$
            Case Is < b$: s$ = sb$: Swap a$, b$ 'our sign is going to be determiined by b$
            Case Is = b$ 'if the two values are the same and are subtracting, our result is zero!
                StringAdd$ = "0" 'How easy was that?
                Exit Function
            Case Else: s$ = sa$ 'our sign is determined by a$
        End Select
        Do
            lb = Len(b$)
            a = Val(Right$(a$, 18)): a$ = Left$(a$, Len(a$) - 18)
            b = Val(Right$(b$, 18)): b$ = Left$(b$, Len(b$) - 18)
            If borrow Then b = b + 1~&& 'in case we had to borrow a digit for the last subtraction
            If a < b Then
                If lb < 18 Then a = a + 10 ^ lb Else a = a + 10 ^ 18
                borrow = -1
            Else
                borrow = 0
            End If
            c = a - b
            temp$ = _Trim$(Str$(c))
            answer$ = String$(18 - Len(temp$), "0") + temp$ + answer$
        Loop Until Len(a$) = 0
        'remove leading 0's
        Do Until Left$(answer$, 1) <> "0"
            answer$ = Mid$(answer$, 2)
        Loop
        'remember to add in the decimal place before finished
        dp = Len(righta$)
        If dp > 0 Then
            answer$ = Left$(answer$, Len(answer$) - dp) + "." + Right$(answer$, dp)
        End If
        StringAdd$ = s$ + answer$
        Exit Function
    End If

    Do
        a1$ = Right$(a$, 18)
        b1$ = Right$(b$, 18)
        a = Val(Right$(a$, 18)): a$ = Left$(a$, Len(a$) - 18)
        b = Val(Right$(b$, 18)): b$ = Left$(b$, Len(b$) - 18)
        c = a + b + carryover
        temp$ = _Trim$(Str$(c))
        If Len(temp$) > 18 Then 'see if we have an answer that is more than 18 digits
            temp$ = Right$(temp$, 18) 'keep 18 digits
            carryover = 1 'store one for carry over
        Else
            carryover = 0 'no carryover
        End If
        answer$ = String$(18 - Len(temp$), "0") + temp$ + answer$
    Loop Until Len(a$) = 0
    If carryover Then answer$ = "1" + answer$
    'remember to add in the decimal place before finished
    dp = Len(righta$)
    If dp > 0 Then
        answer$ = Left$(answer$, Len(answer$) - dp) + "." + Right$(answer$, dp)
    End If
    'remove leading 0's
    Do Until Left$(answer$, 1) <> "0"
        answer$ = Mid$(answer$, 2)
    Loop
    StringAdd$ = sa$ + answer$
End Function

Function StringSubtract$ (tempa$, tempb$)
    a$ = tempa$: b$ = tempb$
    FixNumbers a$, b$
    If Left$(b$, 1) = "-" Then b$ = Mid$(b$, 2) Else b$ = "-" + b$
    StringSubtract$ = StringAdd$(a$, b$)
End Function


Sub FixNumbers (a$, b$)
    'first remove scientific notation and spaces from both
    a$ = _Trim$(N2S$(a$)): b$ = _Trim$(N2S$(b$))
    'then find the decimal position for both and normalize the expressions
    d1 = InStr(a$, "."): d2 = InStr(b$, ".")
    If d1 <> 0 Then 'break down the left and right side of the decimal point for ease of processing  (this is a$)
        lefta$ = Left$(a$, d1 - 1)
        righta$ = Mid$(a$, d1)
    Else
        lefta$ = a$
    End If
    If d2 <> 0 Then 'break down the left and right side of the decimal point for ease of processing  (this is b$)
        leftb$ = Left$(b$, d2 - 1)
        rightb$ = Mid$(b$, d2)
    Else
        leftb$ = b$
    End If

    'normalize the right side of our expressions
    l1 = Len(righta$): l2 = Len(rightb$)
    If l1 < l2 Then
        addzero = l2 - l1
        If l1 = 0 Then righta$ = ".": addzero = addzero - 1
        righta$ = righta$ + String$(addzero, "0")
    ElseIf l1 > l2 Then
        addzero = l1 - l2
        'If l2 = 0 Then rightb$ = ".": addzero = addzero - 1
        rightb$ = rightb$ + String$(addzero, "0")
    End If



    'strip off any plus/minus signs from the two numbers.
    If Left$(lefta$, 1) = "-" Then signa$ = "-": lefta$ = Mid$(lefta$, 2)
    If Left$(leftb$, 1) = "-" Then signb$ = "-": leftb$ = Mid$(leftb$, 2)
    If Left$(lefta$, 1) = "+" Then signa$ = "": lefta$ = Mid$(lefta$, 2)
    If Left$(leftb$, 1) = "+" Then signb$ = "": leftb$ = Mid$(leftb$, 2)
    'normalize the left side of our expressions
    l1 = Len(lefta$): l2 = Len(leftb$)
    If l1 < l2 Then
        addzero = l2 - l1
        lefta$ = String$(addzero, "0") + lefta$
    ElseIf l1 > l2 Then
        addzero = l1 - l2
        leftb$ = String$(addzero, "0") + leftb$
    End If
    'and then put it all together
    a$ = signa$ + lefta$ + righta$
    b$ = signb$ + leftb$ + rightb$
End Sub





Function N2S$ (exp$) 'scientific Notation to String

    t$ = LTrim$(RTrim$(exp$))
    If Left$(t$, 1) = "-" Or Left$(t$, 1) = "N" Then sign$ = "-": t$ = Mid$(t$, 2)

    dp = InStr(t$, "D+"): dm = InStr(t$, "D-")
    ep = InStr(t$, "E+"): em = InStr(t$, "E-")
    check1 = Sgn(dp) + Sgn(dm) + Sgn(ep) + Sgn(em)
    If check1 < 1 Or check1 > 1 Then N2S = exp$: Exit Function 'If no scientic notation is found, or if we find more than 1 type, it's not SN!

    Select Case l 'l now tells us where the SN starts at.
        Case Is < dp: l = dp
        Case Is < dm: l = dm
        Case Is < ep: l = ep
        Case Is < em: l = em
    End Select

    l$ = Left$(t$, l - 1) 'The left of the SN
    r$ = Mid$(t$, l + 1): r&& = Val(r$) 'The right of the SN, turned into a workable long


    If InStr(l$, ".") Then 'Location of the decimal, if any
        If r&& > 0 Then
            r&& = r&& - Len(l$) + 2
        Else
            r&& = r&& + 1
        End If
        l$ = Left$(l$, 1) + Mid$(l$, 3)
    End If

    Select Case r&&
        Case 0 'what the heck? We solved it already?
            'l$ = l$
        Case Is < 0
            For i = 1 To -r&&
                l$ = "0" + l$
            Next
            l$ = "0." + l$
        Case Else
            For i = 1 To r&&
                l$ = l$ + "0"
            Next
    End Select

    N2S$ = sign$ + l$
End Function


Function DWD$ (exp$) 'Deal With Duplicates
    'To deal with duplicate operators in our code.
    'Such as --  becomes a +
    '++ becomes a +
    '+- becomes a -
    '-+ becomes a -
    t$ = exp$
    Do
        bad = 0
        Do
            l = InStr(t$, "++")
            If l Then t$ = Left$(t$, l - 1) + "+" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
        Do
            l = InStr(t$, "+-")
            If l Then t$ = Left$(t$, l - 1) + "-" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
        Do
            l = InStr(t$, "-+")
            If l Then t$ = Left$(t$, l - 1) + "-" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
        Do
            l = InStr(t$, "--")
            If l Then t$ = Left$(t$, l - 1) + "+" + Mid$(t$, l + 2): bad = -1
        Loop Until l = 0
    Loop Until Not bad
    DWD$ = t$
End Function

N2S$ is the function you want.

Thanks!!!!
Reply
#5
SMcNeill

Huh  Any suggestions.  Seems to miss a few conversions, no idea why....  


[Image: RESULT.png]
Reply
#6
From this program:

Code: (Select All)

$CONSOLE:ONLY
DIM A AS DOUBLE

FOR L1 = 1 TO 9
IF L1 = 1 THEN A = 75 / 130
IF L1 = 2 THEN A = 1 / 103
IF L1 = 3 THEN A = 7 / 27
IF L1 = 4 THEN A = 11 / 42
IF L1 = 5 THEN A = 15 / 63
IF L1 = 6 THEN A = 35 / 118
IF L1 = 7 THEN A = 60 / 142
IF L1 = 8 THEN A = 47 / 125
IF L1 = 9 THEN A = 93 / 148

A=A^2
'A$ = StrNum$(A)
ANO$ = N2S$(LTRIM$(STR$(A)))
ANO$=MID$(ANO$,1,6)
P=P + VAL(ANO$)

PRINT ANO$
NEXT

P = (P/9)
ANO$ = N2S$(LTRIM$(STR$(P)))
ANO$=MID$(ANO$,1,6)
PRINT ANO$ + " <- averaged"
color 10
'print "Press any key"
'SLEEP
SYSTEM


' FUNCTION StrNum$ (n)
' value$ = UCASE$(LTRIM$(STR$(n)))
' XPOS1 = INSTR(value$, "D") + INSTR(value$, "E")
' IF XPOS1 THEN
' expo = VAL(MID$(value$, XPOS1 + 1))
' IF VAL(value$) < 0 THEN
' sign$ = "-": value$ = MID$(value$, 2, XPOS1 - 2)
' ELSE value$ = MID$(value$, 1, XPOS1 - 1)
' END IF
' dot = INSTR(value$, "."): L = LEN(value$)
' IF expo > 0 THEN ADD$ = StrNum$(expo - (L - dot), "0")
' IF expo < 0 THEN min$ = StrNum$(ABS(expo) - (dot - 1), "0"): DP$ = "."
' FOR N = 1 TO L
' IF MID$(value$, N, 1) <> "." THEN num$ = num$ + MID$(value$, N, 1)
' NEXT
' ELSE StrNum$ = value$: EXIT FUNCTION
' END IF
' StrNum$ = sign$ + DP$ + min$ + num$ + ADD$
' END FUNCTION


Sub FixNumbers (a$, b$)
'first remove scientific notation and spaces from both
a$ = _Trim$(N2S$(a$)): b$ = _Trim$(N2S$(b$))
'then find the decimal position for both and normalize the expressions
d1 = InStr(a$, "."): d2 = InStr(b$, ".")
If d1 <> 0 Then 'break down the left and right side of the decimal point for ease of processing (this is a$)
lefta$ = Left$(a$, d1 - 1)
righta$ = Mid$(a$, d1)
Else
lefta$ = a$
End If
If d2 <> 0 Then 'break down the left and right side of the decimal point for ease of processing (this is b$)
leftb$ = Left$(b$, d2 - 1)
rightb$ = Mid$(b$, d2)
Else
leftb$ = b$
End If

'normalize the right side of our expressions
l1 = Len(righta$): l2 = Len(rightb$)
If l1 < l2 Then
addzero = l2 - l1
If l1 = 0 Then righta$ = ".": addzero = addzero - 1
righta$ = righta$ + String$(addzero, "0")
ElseIf l1 > l2 Then
addzero = l1 - l2
'If l2 = 0 Then rightb$ = ".": addzero = addzero - 1
rightb$ = rightb$ + String$(addzero, "0")
End If



'strip off any plus/minus signs from the two numbers.
If Left$(lefta$, 1) = "-" Then signa$ = "-": lefta$ = Mid$(lefta$, 2)
If Left$(leftb$, 1) = "-" Then signb$ = "-": leftb$ = Mid$(leftb$, 2)
If Left$(lefta$, 1) = "+" Then signa$ = "": lefta$ = Mid$(lefta$, 2)
If Left$(leftb$, 1) = "+" Then signb$ = "": leftb$ = Mid$(leftb$, 2)
'normalize the left side of our expressions
l1 = Len(lefta$): l2 = Len(leftb$)
If l1 < l2 Then
addzero = l2 - l1
lefta$ = String$(addzero, "0") + lefta$
ElseIf l1 > l2 Then
addzero = l1 - l2
leftb$ = String$(addzero, "0") + leftb$
End If
'and then put it all together
a$ = signa$ + lefta$ + righta$
b$ = signb$ + leftb$ + rightb$
End Sub





Function N2S$ (exp$) 'scientific Notation to String

t$ = LTrim$(RTrim$(exp$))
If Left$(t$, 1) = "-" Or Left$(t$, 1) = "N" Then sign$ = "-": t$ = Mid$(t$, 2)

dp = InStr(t$, "D+"): dm = InStr(t$, "D-")
ep = InStr(t$, "E+"): em = InStr(t$, "E-")
check1 = Sgn(dp) + Sgn(dm) + Sgn(ep) + Sgn(em)
If check1 < 1 Or check1 > 1 Then N2S = exp$: Exit Function 'If no scientic notation is found, or if we find more than 1 type, it's not SN!

Select Case l 'l now tells us where the SN starts at.
Case Is < dp: l = dp
Case Is < dm: l = dm
Case Is < ep: l = ep
Case Is < em: l = em
End Select

l$ = Left$(t$, l - 1) 'The left of the SN
r$ = Mid$(t$, l + 1): r&& = Val(r$) 'The right of the SN, turned into a workable long


If InStr(l$, ".") Then 'Location of the decimal, if any
If r&& > 0 Then
r&& = r&& - Len(l$) + 2
Else
r&& = r&& + 1
End If
l$ = Left$(l$, 1) + Mid$(l$, 3)
End If

Select Case r&&
Case 0 'what the heck? We solved it already?
'l$ = l$
Case Is < 0
For i = 1 To -r&&
l$ = "0" + l$
Next
l$ = "0." + l$
Case Else
For i = 1 To r&&
l$ = l$ + "0"
Next
End Select

N2S$ = sign$ + l$
End Function


Function DWD$ (exp$) 'Deal With Duplicates
'To deal with duplicate operators in our code.
'Such as -- becomes a +
'++ becomes a +
'+- becomes a -
'-+ becomes a -
t$ = exp$
Do
bad = 0
Do
l = InStr(t$, "++")
If l Then t$ = Left$(t$, l - 1) + "+" + Mid$(t$, l + 2): bad = -1
Loop Until l = 0
Do
l = InStr(t$, "+-")
If l Then t$ = Left$(t$, l - 1) + "-" + Mid$(t$, l + 2): bad = -1
Loop Until l = 0
Do
l = InStr(t$, "-+")
If l Then t$ = Left$(t$, l - 1) + "-" + Mid$(t$, l + 2): bad = -1
Loop Until l = 0
Do
l = InStr(t$, "--")
If l Then t$ = Left$(t$, l - 1) + "+" + Mid$(t$, l + 2): bad = -1
Loop Until l = 0
Loop Until Not bad
DWD$ = t$
End Function

I get this output on Debian Linux:

Code: (Select All)
.33284
0.0000
.06721
0.0685
0.0566
0.0879
.17853
.14137
.39485
.14753 <- averaged

So I don't know where you're pulling a much-longer list of strange numbers from.

I noticed your `StrNum$()` routine uses recursion, which is one thing fundamentally wrong with it. You should not need recursion to detect a `D` or `E`, or anything else in a floating-point numerical value in scientific notation in BASIC.
Reply
#7
why not use print using ?
Code: (Select All)

print using "#####.#####"; 8.89d-2 
Reply
#8
or if you want the result in a string
Code: (Select All)

Declare Library
    Function snprintf& (Dest As String, Byval l As Long, frmt As String, Byval x As Double)
End Declare


For L1 = 1 To 9
    If L1 = 1 Then A = 75 / 130
    If L1 = 2 Then A = 1 / 103
    If L1 = 3 Then A = 7 / 27
    If L1 = 4 Then A = 11 / 42
    If L1 = 5 Then A = 15 / 63
    If L1 = 6 Then A = 35 / 118
    If L1 = 7 Then A = 60 / 142
    If L1 = 8 Then A = 47 / 125
    If L1 = 9 Then A = 93 / 148

    A = A ^ 2
    A$ = StrNum$(A, 5, "f")
    A$ = Mid$(A$, 1, 6)
    P = P + Val(A$)

    Print A$
Next

P = (P / 9)
A$ = StrNum$(P, 5, "f")
A$ = Mid$(A$, 1, 6)
Print A$ + " <- averaged"
Color 10
Print "Press any key"
Sleep

Function StrNum$ (x As Double, places As Integer, format As String)
    Dim As String s
    Dim As String frmt
    Dim As Long l, ex, sign
    sign = Sgn(x)
    If sign < 0 Then x = -x
    s = Spc(64)
    frmt = "%." + _Trim$(Str$(places)) + format + Chr$(0)
    l = snprintf(s, Len(s), frmt, x)
    s = _Trim$(s)
    If InStr(s, ".") > 0 And Left$(s, 1) = "0" Then s = Mid$(s, 2)
    If sign < 0 Then s = "-" + s Else s = " " + s
    ex = InStr(s, "e")
    If ex > 0 Then Mid$(s, ex, 1) = "D"
    StrNum$ = s
End Function
Reply
#9
The program calculates the probability for data stored in a 2 dimensional array 112,13.
Five digits to the right of the decimal is what I am using but can change if necessary to
improve the overall function of the program.  

The problem is not with the N2S$ function as I have a test program so that I can look 
up the values from the array for each calculation, when I plug them in directly it outputs 
the correct formatted value.

I have changed the data type for the array to Single, double, _float but nothing helps.
The program works by cycling through the array pulling out two values then calculates 
the probability, simple.  I write the output values to a file making it easy to test.  The
probabilities are also stored in another array for the next stage of processing.   

The function was added to my main program,  Like I said it pulls out two values from the 
array then simply divides them to get a probability.  This probability is then copied to a 
string A$=Ltrim$(Str$(A)) then ran through the N2S$ function to check for scientific notation
and if so then convert it.  The string is then adjusted to a preset length. A$=Mid$(A$,1,6), etc.

Like I said the N2S$ works perfect when I use the test tool but fails in the body of the main 
code.  Both are almost identical as far as the calculations, one works the other, not so much.
I am processing millions of cycles overall so speed is a factor.

Any thoughts/ideas are welcome.

R1
Reply
#10
(10-12-2023, 09:32 AM)Jack Wrote: Thanks, will try it.

R1



or if you want the result in a string
Code: (Select All)

Declare Library
    Function snprintf& (Dest As String, Byval l As Long, frmt As String, Byval x As Double)
End Declare


For L1 = 1 To 9
    If L1 = 1 Then A = 75 / 130
    If L1 = 2 Then A = 1 / 103
    If L1 = 3 Then A = 7 / 27
    If L1 = 4 Then A = 11 / 42
    If L1 = 5 Then A = 15 / 63
    If L1 = 6 Then A = 35 / 118
    If L1 = 7 Then A = 60 / 142
    If L1 = 8 Then A = 47 / 125
    If L1 = 9 Then A = 93 / 148

    A = A ^ 2
    A$ = StrNum$(A, 5, "f")
    A$ = Mid$(A$, 1, 6)
    P = P + Val(A$)

    Print A$
Next

P = (P / 9)
A$ = StrNum$(P, 5, "f")
A$ = Mid$(A$, 1, 6)
Print A$ + " <- averaged"
Color 10
Print "Press any key"
Sleep

Function StrNum$ (x As Double, places As Integer, format As String)
    Dim As String s
    Dim As String frmt
    Dim As Long l, ex, sign
    sign = Sgn(x)
    If sign < 0 Then x = -x
    s = Spc(64)
    frmt = "%." + _Trim$(Str$(places)) + format + Chr$(0)
    l = snprintf(s, Len(s), frmt, x)
    s = _Trim$(s)
    If InStr(s, ".") > 0 And Left$(s, 1) = "0" Then s = Mid$(s, 2)
    If sign < 0 Then s = "-" + s Else s = " " + s
    ex = InStr(s, "e")
    If ex > 0 Then Mid$(s, ex, 1) = "D"
    StrNum$ = s
End Function
Reply




Users browsing this thread: 6 Guest(s)