Posts: 660
Threads: 142
Joined: Apr 2022
Reputation:
58
Easy enough to work around, just really annoying. I had half hoped there was an accurate math setting I wasn't aware of...
Posts: 3,978
Threads: 177
Joined: Apr 2022
Reputation:
220
12-01-2022, 08:40 PM
(This post was last modified: 12-01-2022, 08:41 PM by bplus.)
(11-30-2022, 08:42 PM)justsomeguy Wrote: You could try for the same effect.
Code: (Select All) DIM x AS INTEGER
FOR x = 100 TO 5 STEP -5
PRINT x / 100
_DELAY x / 100
NEXT x
@justsomeguy had the workaround in first reply. I had to work my way up to it this morning to see why!
And I saw in another thread a version of this thread subject, Steve offering the same.
FOR loop structure may be the most Basic but not the most efficient.
b = b + ...
Posts: 2,177
Threads: 222
Joined: Apr 2022
Reputation:
104
12-01-2022, 10:16 PM
(This post was last modified: 12-01-2022, 10:18 PM by Pete.)
@bplus
I figured the problem was the way the numbers were being generated in the loop, I see you came to the same conclusion, but that's what these routines are supposed to try to alleviate. So it finally dawned on me to place some conditions on the loop and run the counting variables DOUBLE. It worked, as tested, to 10,000. Glitches beyond that for my function or Steve's, who knows. This kept me in business back in the early 1990's.
These two rounding functions will now match and complete.
Code: (Select All) cnt = 100000
DIM AS DOUBLE a, x
a = -.01
FOR x = 1000 TO -0.001 STEP a
a$ = pete(x): b$ = Round2$(x, -2)
PRINT cnt, x;: LOCATE , 40: PRINT "Pete = "; a$;: LOCATE , 55: PRINT "Steve = "; b$
IF LEN(olda$) <> 0 AND ABS(VAL(a$) - VAL(olda$)) <> .01 OR LEN(oldb$) <> 0 AND ABS(VAL(b$) - VAL(oldb$)) <> .01 THEN
BEEP: DO: WHILE _MOUSEINPUT: WEND: LOOP UNTIL _MOUSEBUTTON(1): _DELAY .1
END IF
cnt = cnt - 1
olda$ = a$
oldb$ = b$
NEXT
FUNCTION pete$ (x)
tmp1$ = ".00"
tmp2$ = LTRIM$(STR$(INT(x * 100 + .5) / 100))
IF INSTR(tmp2$, ".") THEN
MID$(tmp1$, 2, LEN(tmp2$)) = MID$(tmp2$, INSTR(tmp2$, ".") + 1)
tmpint$ = MID$(tmp2$, 1, INSTR(tmp2$, ".") - 1)
ELSE
tmpint$ = tmp2$
END IF
pete$ = tmpint$ + tmp1$
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
FUNCTION Round2$ (anyNumber AS _FLOAT, dp AS LONG) ' uses N2S$
' 5 and up at decimal place dp+1 > +1 at decimal place 4 and down > +0 at dp
'2 1 0.-1 -2 -3 -4 ... pick dp like this for this Round$ Function
DIM sn$, dot, predot, postdot, rtn$
sn$ = N2S$(STR$(anyNumber + .5 * 10 ^ dp)) 'get rid of sci notation, steve trims it so next find dot
dot = INSTR(sn$, ".")
IF dot THEN
predot = dot - 1
postdot = LEN(sn$) - (dot + 1)
ELSE
predot = LEN(sn$)
postdot = 0
END IF
' xxx.yyyyyy dp = -2
' ^ dp
IF dp >= 0 THEN
rtn$ = MID$(sn$, 1, predot - dp) + STRING$(dp, "0")
ELSE
rtn$ = MID$(sn$, 1, predot) + "." + MID$(sn$, dot + 1, -dp)
END IF
IF rtn$ = "" THEN Round2$ = "0" ELSE Round2$ = rtn$
END FUNCTION
Pete
Shoot first and shoot people who ask questions, later.
|