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

ryu incorrectly formats this f32 number #235

Open
e00E opened this issue Oct 2, 2024 · 1 comment
Open

ryu incorrectly formats this f32 number #235

e00E opened this issue Oct 2, 2024 · 1 comment

Comments

@e00E
Copy link

e00E commented Oct 2, 2024

An f32 (32 bit floating point value) can represent the number 2147483904 exactly. Ryu formats this number incorrectly. Ryu formats the number as the string 2.147484E9. Ryu should format the number as the string 2147483904.

This is a bug in Ryu because it violates correctness criteria 3 from the paper, "correct rounding". Both strings satisfy criteria 1 and 2 but the string 2147483904 is closer to the original number. It has a distance of 0 to the number. Ryu's output has a distance of 96.

@inkydragon
Copy link

Since julia use ryu as its default float point to string algorithm.
I've written a small julia script, to find bad output of ryu.
ryu-f32-test.jl

As a result, it seems like a half of the test cases were failed.

(all_error_count = 35567695, test_case_count = 75497472, error_ratio = 0.4711110724343194)

For further confirmation, I hand-picked some test samples and used the Dragonbox algorithm for confirmation:
godbolt online playground: https://godbolt.org/z/6vqn74jMY

IEEE 754 floating-point formatter using the Dragonbox algorithm
        f32(%a)     uint32        int64             str(f32)
        0x1p+25  0x2000000     33554432      33554432.000000
        0x1p+26  0x4000000     67108864      67108864.000000
        0x1p+27  0x8000000    134217728     134217728.000000
        0x1p+28 0x10000000    268435456     268435456.000000
        0x1p+29 0x20000000    536870912     536870912.000000
        0x1p+30 0x40000000   1073741824    1073741824.000000
        0x1p+31 0x80000000   2147483648    2147483648.000000
 0x1.000002p+31 0x80000100   2147483904    2147483904.000000

You may want to test ryu with those cases, add new test cases here:

TEST(F2sTest, Regression) {

  // issue#235
  ASSERT_F2S("3.3554432E7", 0x1p+25f);  // good
  ASSERT_F2S("6.7108864E7", 0x1p+26f);  // good
  ASSERT_F2S("1.34217728E8", 0x1p+27f);
  ASSERT_F2S("2.68435456E8", 0x1p+28f);
  ASSERT_F2S("5.36870912E8", 0x1p+29f);
  ASSERT_F2S("1.073741824E9", 0x1p+30f);
  ASSERT_F2S("2.147483648E9", 0x1p+31f);
  ASSERT_F2S("2.147483904E9", 0x1.000002p+31f);
  ASSERT_F2S("2.147483904E9", 2147483904.0f);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants