Skip to content
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

floating point errors #9237

Closed
todbot opened this issue May 10, 2024 · 2 comments
Closed

floating point errors #9237

todbot opened this issue May 10, 2024 · 2 comments
Labels

Comments

@todbot
Copy link

todbot commented May 10, 2024

CircuitPython version

Adafruit CircuitPython 9.1.0-beta.1-18-g781c577745 on 2024-05-05; Adafruit QT Py RP2040 with rp2040

Code/REPL

print("Hello, Pi Pico!")

print("0.004 = ", 0.004)
print("1000 = ", 1000)
print("0.004 * 1000 = ", 0.004 * 1000)
print("int(0.004 * 1000) = ", int(0.004 * 1000))
print('"%f" % (0.004 * 1000) = ', "%f" % (0.004 * 1000))

Behavior

Prints out a "3" instead of a "4" on the second-to-last line and "3.999998" instead of "4.000000"

Hello, Pi Pico!
0.004 =  0.004
1000 =  1000
0.004 * 1000 =  4.0
int(0.004 * 1000) =  3
"%f" % (0.004 * 1000) =  3.999998

Description

The crux of the issue is that int(0.004 * 1000) prints out "3" instead of "4".

It's unclear to me why it does this, both numbers have pretty simple representations in IEEE754 (using https://www.h-schmidt.net/FloatConverter/IEEE754.html, 0.004 is actually 0.0040000001899898052215576171875, 1000 is actually 1000)

This error does not exist in MicroPython v1.22.0 on 2023-12-27.

Here are two wokwis to compare:

Additional information

No response

@todbot todbot added the bug label May 10, 2024
@justmobilize
Copy link

@todbot I do see if I remove that last bit of mantissa (which CP doesn't have) it's 0.0039999997, which would match your results...

@dhalbert
Copy link
Collaborator

Remove that last two bits for what CircuitPython has. As I mentioned in discord, the CircuitPython default for objects is OBJ_REPR_C. MicroPython defaults to OBJ_REPR_A. See

circuitpython/py/mpconfig.h

Lines 105 to 107 in d8ca842

/* Object representation */
// A MicroPython object is a machine word having the following form:

and following.

See also #5802, #1220, #566, #230, and the MicroPython issues those issues reference.

This is always going to be a problem with floats. It's worse the fewer bits of precision you have. MicroPython has improved its printing of floats over the years, and of course we've incorporated that, but there is is a trade-off between "reasonable" and seemingly more exact.

We could consider going to boxed floats, but for lots of floats in lists (not array.array), it uses up a lot of storage.

@dhalbert dhalbert closed this as not planned Won't fix, can't repro, duplicate, stale May 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants