Menu

#728 strtoflt128() assigns some subnormal values incorrectly

v1.0 (example)
closed-invalid
nobody
None
3
2020-04-25
2018-04-26
Sisyphus
No

There are lots of cases where strtoflt128() is not assigning subnormal values correctly - and the error can be far more than just a few ULPs.
The values that are causing the problems, seem to fall into 3 categories:

1) strings of the form D.dd...e-4951 where "D" is either "1", "2", or "3" (eg "1.864043e-4951", "2.819208e-4951" and "3.58e-4951");
2) strings of the form 1.dd...e-4941 (eg "1.242435e-4941");
3) strings of the form D.dd...e-4942 where "D" is either "8" or "9" (eg "8.176823e-4942", "9.74e-4942").

I don't mean that every string that fits one of those categories will inevitably be assigned incorrectly - it's just that the values I've found to be miscalculated always fit one of those categories.
For example, I find 3.08e-4951, 3.18e-4951, 3.28e-4951, 3.38e-4951, 3.48e-4951 and 3.58e-4951 are assigned incorrectly, but 3.68e-4951 is assigned correctly.

No such problem on Ubuntu - it's just the Windows strtoflt128() calculation that can be inaccurate.
(On Windows, I have a range of mingw compilers from 4.7.0 through to 7.2.0, and the behaviour is the same for all of them.
On Ubuntu, I have only gcc-5.4.0.)

Attached is the C program that demonstrates the anomalies for 2 specific values.
It firstly calculates 3.58e-4951 as:

f1 = strtoflt128("3.58e-4951", NULL);
and then as
f2 = 358 * (5 ^ -4953) * (2 ^ -4953);

f1 and f2 should be equivalent but the significands are quite different on Windows, where:

f1 = 3.58000000021311022967612420460407998e-4951
= 0x0.0000000000000001f6d797affeffp-16382
f2 = 3.57999999999999926614517992215333485e-4951
= 0x0.0000000000000001f6d797af7e6fp-16382

On Ubuntu, f1 and f2 have the same value:

f1 = 3.57999999999999926614517992215333485e-4951
= 0x0.0000000000000001f6d797af7e6fp-16382
f2 = 3.57999999999999926614517992215333485e-4951
= 0x0.0000000000000001f6d797af7e6fp-16382

and I've confirmed that the Ubuntu result is correct, according to mpfr-4.0.

Next, the C program calculates (using the same approaches) 9.74e-4942:

f1 = strtoflt128("9.74e-4942", NULL);
f2 = 974 * (5 ^ -4944) * (2 ^ -4944);

Again, Windows produces conflicting results:

f1 = 9.74000000200773726651588279988191118e-4942
= 0x0.000000013e87318d3ff77faea7fep-16382
f2 = 9.73999999999999999999999693066104753e-4942
= 0x0.000000013e87318c25f66e2e8318p-16382

and Ubuntu produces correct results:

f1 = 9.73999999999999999999999693066104753e-4942
= 0x0.000000013e87318c25f66e2e8318p-16382
f2 = 9.73999999999999999999999693066104753e-4942
= 0x0.000000013e87318c25f66e2e8318p-16382

Cheers,
Rob

1 Attachments

Discussion

  • Sisyphus

    Sisyphus - 2018-04-29

    I've found that the affected subnormals are all either in the range 1.8226001020320419902366105930885830e-4951 to 3.6451995318824681273532864955943088e-4951 (0x1.00000318p-16446 to 0x1.ffffffffffffp-16446), or in the range 7.8280063884148688667050511979538776e-4942 to 1.5656012776829737733410095920732635e-4941 (0x1p-16414 to 0x1.ffffffffffffffffffffp-16414).

    I've checked thousands of random values inside both ranges and, for the former range, I'm finding that only approximately 0.5% of those values are being assigned correctly.
    For the latter range, all of the values I've tested have been assigned incorrectly.

    I haven't struck any problem with values that fall outside of those 2 ranges.

    Cheers,
    Rob

     
  • Sisyphus

    Sisyphus - 2020-04-25

    Apparently this is a gcc libquadmath bug, and nothing to do with mingw-w64.
    (I'll therefore close this report if I can wotk out how to.)

    I have lodged a bug report about this issue with gcc's bugzilla at:
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94756

    Cheers,
    Rob

     
  • LIU Hao

    LIU Hao - 2020-04-25
    • status: open --> closed-invalid
     

Log in to post a comment.

MongoDB Logo MongoDB