NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
port-vax/59264: t_strtod:strtod_gherman_bug test is failing
>Number: 59264
>Category: port-vax
>Synopsis: t_strtod:strtod_gherman_bug test is failing
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-vax-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Apr 07 00:50:00 +0000 2025
>Originator: Taylor R Campbell
>Release: current
>Organization:
The VaxBSD Floating-point Halfway House
>Environment:
>Description:
Termination reason
FAILED: 1 checks failed; see output for more details
Standard error stream
*** Check failed: /tmp/build/2025.04.04.21.52.19-vax/src/tests/lib/libc/stdlib/t_strtod.c:334: d != 0x1.d34fd8378ea83p+0: d=1.82544=0xe.9a7ec1bc7541cp-3
https://releng.netbsd.org/b5reports/vax/2025/2025.04.04.21.52.19/test.html#lib_libc_stdlib_t_strtod_strtod_gherman_bug
Relevant information about the bug in parsing the decimal notation for a number verrrrrrrrrrry close to halfway between two binary floating-point numbers:
https://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/
https://web.archive.org/web/20241212101326/https://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/
The notation is confusing because printf on VAX uses 0xe as the leading hex digit instead of 0x1, but once you shift it, you see the result is off by a single bit in the least significant place:
Expected: 0x1.d34fd8378ea830p+0
VAXctual: 0x1.d34fd8378ea838p+0
^
Before the Geza Herman bug fix chronicled at https://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/, strtod would erroneously return 0x1.d34fd8378ea84p+0 _in IEEE 754 binary64 arithmetic_.
But IEEE 754 binary64 arithmetic uses 53-bit precision, whereas VAX D (double) arithmetic uses 56-bit precision.
I used Sollya and MIT Scheme to verify that the answer we compute on VAX is correct:
;;; Sollya, with 1000-bit floating-point approximation
> prec=1000;
The precision has been set to 1000 bits.
> display = hexadecimal;
Display mode is hexadecimal numbers.
> round(1.8254370818746402660437411213933955878019332885742187, double, RN);
Warning: Rounding occurred when converting the constant "1.8254370818746402660437411213933955878019332885742187" to floating-point with 1000 bits.
If safe computation is needed, try to increase the precision.
0x1.d34fd8378ea83p0
> round(1.8254370818746402660437411213933955878019332885742187, 53, RN);
Warning: Rounding occurred when converting the constant "1.8254370818746402660437411213933955878019332885742187" to floating-point with 1000 bits.
If safe computation is needed, try to increase the precision.
0x1.d34fd8378ea83p0
> round(1.8254370818746402660437411213933955878019332885742187, 56, RN);
Warning: Rounding occurred when converting the constant "1.8254370818746402660437411213933955878019332885742187" to floating-point with 1000 bits.
If safe computation is needed, try to increase the precision.
0x1.d34fd8378ea838p0
;;; MIT Scheme, entirely with arbitrary-precision bignum integer arithmetic -- note that we start with a leading 1 bit, so the inner shift is by p-1 (p=53 for binary64, p=55 for VAX D), not by p; then the outer shift is to adjust the leading hexadecimal digit to match.
(number->string (* 16 (round (* #e1.8254370818746402660437411213933955878019332885742187 (expt 2 52)))) #x10)
;Value: "1d34fd8378ea830"
(number->string (* 2 (round (* #e1.8254370818746402660437411213933955878019332885742187 (expt 2 55)))) #x10)
;Value: "1d34fd8378ea838"
>How-To-Repeat:
cd /usr/tests/lib/libc/stdlib
atf-run t_strtod | atf-report
>Fix:
#if DBL_MANT_DIG == 53
ATF_CHECK_EQ_MSG(d, 0x1.d34fd8378ea83p+0, "d=%g=%a", d, d);
#elif DBL_MANT_DIG == 56
ATF_CHECK_EQ_MSG(d, 0x1.d34fd8378ea838p+0, "d=%g=%a", d, d);
#else
# error Fill in the correct answer for this machine's DBL_MANT_DIG!
#endif
Home |
Main Index |
Thread Index |
Old Index