This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug stdio/22752] New: strtold/printf errors for "long double" on ppc64
- From: "allan.haldane at gmail dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Fri, 26 Jan 2018 23:18:35 +0000
- Subject: [Bug stdio/22752] New: strtold/printf errors for "long double" on ppc64
- Auto-submitted: auto-generated
https://sourceware.org/bugzilla/show_bug.cgi?id=22752
Bug ID: 22752
Summary: strtold/printf errors for "long double" on ppc64
Product: glibc
Version: 2.26
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: stdio
Assignee: unassigned at sourceware dot org
Reporter: allan.haldane at gmail dot com
Target Milestone: ---
I've noticed two possible bugs related to reading/writing "long double" types
on ppc64, where it has the "IBM double double" 128-bit binary format.
First, it is possible to construct two values whose printf output is identical,
but which are not equal. This has to do with treatment of the 107th bit, which
was also discussed here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70117
It is not clear to me whether glibc is right to ignore the 107th bit and treat
them equal, and that gcc should also ignore the 107th bit, or not.
---------------- Example 1 -------------
#include <stdio.h>
#include <stdint.h>
union unpack{
struct { uint64_t a, b; } ip;
long double d;
};
int main(){
/* equiv to strtold("2")/strtold("3") */
union unpack x = {4604180019048437077ull, 4360985639170430293ull};
/* equiv to strtold("0.66666666666666666666666666666666") */
union unpack y = {4604180019048437077ull, 4360985639170430292ull};
printf("%.40Lg\n", x.d);
printf(x.d == y.d ? "==\n" : "!=\n");
printf("%.40Lg\n", y.d);
}
------ Output (glibc 2.26, gcc 7.3.0) -------
0.6666666666666666666666666666666584493656
!=
0.6666666666666666666666666666666584493656
---------------------------------------------
Second, strtold fails for any long-double which is subnormal or near-subnormal.
The following example shows it is possible to create the value '5e-294' by
division, but strtold fails to read it because the lower double is subnormal.
It actually writes the correct value but still sets errno, so the fix might be
as simple as not setting errno.
---------------- Example 2 -------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(){
long double x;
char str[1024], *end;
x = strtold("5.0e-292", &end)/100;
printf("%.40Lg\n", x);
/* reconstruct x from its string representation */
snprintf(str, 1024, "%.40Lg", x);
x = 0; /* reset to 0 to see if it gets overwritten */
errno = 0;
x = strtold(str, &end);
if (errno != 0) {
printf("error: %s\n", strerror(errno));
}
printf("%.40Lg\n", x);
}
------ Output (glibc 2.26, gcc 7.3.0) -------
5.000000000000000000000000000002042787298e-294
error: Numerical result out of range
5.000000000000000000000000000002042787298e-294
---------------------------------------------
--
You are receiving this mail because:
You are on the CC list for the bug.