SOB code has me swearing, every time I think I have some accuracy in display settled, someone comes up with something to shake my faith.
@Pete
Took me a long time to figure out what was going on, not pleasantly!
Here it is!
You (we) are (were) expecting x of a single type in the FOR loop to be better behaved than any other single type!
I have no idea why it decides not to round up at the 2 places in 10,000 numbers but look at those freak'n x values wandering as much as .005 off the expected value!
I did an equivalent test like yours dropping integers down: For cnt = 10000 to 1 step -1
only setting x = cnt/100 and x doesn't wander nearly as much as .005 and so roundDP$ returns expected results.
BTW Round2$ was old code that failed with negative numbers.
I am glad I did do this because I am updating GUI for new dialogs in v3.4.1 and I was using the buggy Round2$ code that failed with neg numbers.
BTW I get something short of 5000 lines in Console, good to know.
@Pete
Took me a long time to figure out what was going on, not pleasantly!
Here it is!
Code: (Select All)
For x = 100 To -.001 Step -.01
You (we) are (were) expecting x of a single type in the FOR loop to be better behaved than any other single type!
I have no idea why it decides not to round up at the 2 places in 10,000 numbers but look at those freak'n x values wandering as much as .005 off the expected value!
I did an equivalent test like yours dropping integers down: For cnt = 10000 to 1 step -1
only setting x = cnt/100 and x doesn't wander nearly as much as .005 and so roundDP$ returns expected results.
BTW Round2$ was old code that failed with negative numbers.
Code: (Select All)
$Console:Only
''test DP$ 2022-10-14 another Round Helper
'For n = 1 To 10000
' If n = 7658 Then Beep: Flag = -1
' a = n / 100
' r$ = roundDP$(a, 2)
' Print n, a, r$
' If n Mod 20 = 0 Then
' If Flag Then Sleep
' Cls
' End If
'Next
'Dim x ' ref Pete's test https://staging.qb64phoenix.com/showthread.php?tid=1209&pid=10895#pid10895
'cnt = 10000
'For x = 100 To -.001 Step -.01
' a$ = roundDP$(x, 2)
' Print cnt, x;: Locate , 30: Print "Steve = "; a$
' 'Rem IF cnt <> VAL(MID$(a$, 1, INSTR(a$, ".") - 1) + MID$(a$, INSTR(a$, ".") + 1)) THEN DO: WHILE _MOUSEINPUT: WEND: LOOP UNTIL _MOUSEBUTTON(1): _DELAY .1
' 'If Len(olda$) And Abs(Val(a$) - Val(olda$)) <> .01 Then Beep: Do: While _MouseInput: Wend: Loop Until _MouseButton(1): _Delay .1
' If Len(olda$) And Abs(Val(a$) - Val(olda$)) <> .01 Then Beep: Sleep ' <<< b= mod this is less confusing than above
' cnt = cnt - 1
' olda$ = a$
' 'If cnt Mod 10 = 0 Then ' check screens
' ' Sleep
' ' Cls
' 'End If
'Next
Dim cnt As Long, x As Single
For cnt = 10000 To 5000 Step -1
x = cnt / 100
a$ = roundDP$(x, 2)
Print cnt, x;: Locate , 30: Print "Steve = "; a$
'Rem IF cnt <> VAL(MID$(a$, 1, INSTR(a$, ".") - 1) + MID$(a$, INSTR(a$, ".") + 1)) THEN DO: WHILE _MOUSEINPUT: WEND: LOOP UNTIL _MOUSEBUTTON(1): _DELAY .1
'If Len(olda$) And Abs(Val(a$) - Val(olda$)) <> .01 Then Beep: Do: While _MouseInput: Wend: Loop Until _MouseButton(1): _Delay .1
If Len(olda$) And Abs(Val(a$) - Val(olda$)) <> .01 Then Beep: Sleep ' <<< b= mod this is less confusing than above
olda$ = a$
'If cnt Mod 20 = 0 Then ' check screens
' Sleep
' Cls
'End If
Next
Function roundDP$ (num, digits) 'flaw if expontential notation involved.
Print "roundDP recd this num"; num
s$ = N2S$(Str$(num + Sgn(num) * (.5 * (10 ^ -digits))))
dot = InStr(s$, ".")
If dot Then r$ = Mid$(s$, 1, dot + digits) Else r$ = s$
roundDP$ = r$
End Function
Function N2S$ (EXP$) 'remove scientific Notation to String (~40 LOC)
'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
ReDim t$, sign$, l$, r$, r&&
ReDim dp As Long, dm As Long, ep As Long, em As Long, check1 As Long, l As Long, i As Long
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 = _Trim$(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$ = "." + l$
Case Else
For i = 1 To r&&
l$ = l$ + "0"
Next
l$ = l$
End Select
N2S$ = sign$ + l$
End Function
I am glad I did do this because I am updating GUI for new dialogs in v3.4.1 and I was using the buggy Round2$ code that failed with neg numbers.
BTW I get something short of 5000 lines in Console, good to know.
b = b + ...