-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Float rounding error: 0.95 + 0.05 = 0 in some cases #195
Comments
Start at 0.8 and increment by 0.05 and it'll hit 1 correctly. Floating point: ex= Start at 0.75 and increment by 0.05 and it trips when it should be 1. Floating point: ex= As expected, this explains why it's able to continue to 1.05: it's accruing 0.05 steps using the inherently inaccurate floating point format, then mis-handling a narrow range of mantissa values.
|
A simpler way to repro the issue, for faster test iteration:
Expected: 1 This specific example stopped working in ROM 920177. (Whether earlier ROMs had float interpretation issues, I don't know yet.) The specific change for this release was not committed to the repo. All changes from 920173 to 920183 are present in this commit: https://github.com/MEGA65/mega65-rom/commit/8b5b60d3b6b5587bdff409861a3315bd674a6b70 Many source formatting changes were introduced in this range, making it difficult to glean what parts of the code have introduced the incorrect behavior. |
In ROM 920176, the float representation test program above (where I'm poking into the I variable) produces the same result. This may suggest that the error is not in the float representation, but in the handling of the result. Notice that the It appears something has changed slightly with regards to float mantissa rounding, but a discontinuity where a few increasing mantissa values just before "1" are interpreted as "0" is likely wrong. |
Maybe connected: |
Agreed, I assume that's the issue. Multiplying the slightly-off float by 10 (decimal) appears to also result in a 0, but that might be a coincidence that's still accounted for by the decimal conversion in PRINT. |
Oh crap it's INT again. 😂 The breaking change https://github.com/MEGA65/mega65-rom/commit/8b5b60d3b6b5587bdff409861a3315bd674a6b70 made only one change to
|
My apologies, I made a dumb mistake in my test data above: I got the mantissa byte ordering wrong. :P I deleted the errors from my previous messages to avoid confusion. In the "compact" five-byte format used for float variables, bit 7 of the least significant byte is the sign bit. With mantissa bytes ordered from MSB to LSB, the erroneous +0.05 sequence looks like this:
Incrementing the mantissa by one up to
Sure enough, with FAC set to Stepping through |
Now that I know what I'm doing (sorta), I can confirm that in ROM 920176, setting a variable's memory to As above, I will assume for now that |
I fixed a fault with The
The change that caused this was a change to float rounding introduced in ROM 920177. Consider this test program:
C64, C65, and MEGA65 all miss the 0 due to compounding float inaccuracies, and all software engineers are taught to expect this from floats. It is still notable that the compounding error is just a teeny bit worse after ROM 920177. I don't yet believe there's a reason to try and get the rounding behavior to match exactly, but it's worth remembering in case we discover any other odd behaviors that may have escaped scrutiny. The good news is that in this case, I'm confident that |
Test Environment (required)
You can use MEGA65INFO to retrieve this.
Describe the bug
outputs "0" instead of "1" in the list:
Note that replacing line 20 with
PRINT I*10
still shows 0 in that spot, so it might not just be rounding incorrectly duringPRINT
.It's not specific to
FOR STEP
. This fails in the same way:PRINT 0.95+0.05
outputs the correct result.The text was updated successfully, but these errors were encountered: