strtod does not behave as documented on underflow. Function and documentation should converge to proper behavior
| Originator: | pascal.cuoq | ||
| Number: | rdar://25141128 | Date Originated: | 2016-03-14 |
| Status: | Open | Resolved: | |
| Product: | OS X SDK | Product Version: | |
| Classification: | Reproducible: | always |
Summary:
On OS X 10.9.5, with Clang “Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)” version installed, the attached program produces when compiled:
$ clang t.c &&./a.out
0x1p-1023
0x1p-1024
0x1p-1070
0
0x1p-1023
0x1p-1024
0x1p-1070
0 (ERANGE is 34)
0x1p-1023
0x1p-1024
0x1p-1070
34
This is not what is described on the man page, that is:
“If the correct value would cause underflow, zero is returned and ERANGE is stored in errno.”
It is good that the behavior is not that of the man page, because the behavior described in the man page is undesirable. The man page should be fixed to indicate that the closest representable value is returned on underflow (and ERANGE is stored in errno).
A second problem appears to be that ERANGE is not stored in errno for hexadecimal representations.
The behavior obtained on Linux is the following:
0x0.8p-1022
0x0.4p-1022
0x0.000000000001p-1022
0
0x0.8p-1022
0x0.4p-1022
0x0.000000000001p-1022
34 (ERANGE is 34)
0x0.8p-1022
0x0.4p-1022
0x0.000000000001p-1022
34
Although Linux has the same documentation bug, the above seems like the ideal behavior, and OS X's strtod should provide the same one.
(Note that the first three calls to strtod do not cause underflow, because the conversions are not inexact. It is correct not to set errno to ERANGE for the first three calls to strtod in t.c.)
Steps to Reproduce:
Install the command-line compilation tools.
Type:
clang t.c && ./a.out
Type:
man strtod
Expected Results:
0x0.8p-1022
0x0.4p-1022
0x0.000000000001p-1022
0
0x0.8p-1022
0x0.4p-1022
0x0.000000000001p-1022
34 (ERANGE is 34)
0x0.8p-1022
0x0.4p-1022
0x0.000000000001p-1022
34
The man page does not say that 0 is returned on underflow
Actual Results:
0x1p-1023
0x1p-1024
0x1p-1070
0
0x1p-1023
0x1p-1024
0x1p-1070
0 (ERANGE is 34)
0x1p-1023
0x1p-1024
0x1p-1070
34
The man page says that 0 is returned on underflow
Version:
OS X 10.9.5
XCode 5.1.1
Notes:
Configuration:
Attachment t.c:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void) {
printf("%a\n%a\n%a\n", strtod("0x1.0p-1023",0), strtod("0x1.0p-1024",0),
strtod("0x1.0p-1070",0) );
printf("%d\n", (int) errno);
printf("%a\n%a\n%a\n", strtod("0x1.fffffffffffffp-1024",0),
strtod("0x1.fffffffffffffp-1025",0), strtod("0x1.fffffffffffffp-1071",0) );
printf("%d (ERANGE is %d)\n", (int) errno, (int)ERANGE);
errno=0;
printf("%a\n%a\n%a\n", strtod("1.1125369292536007e-308",0),
strtod("5.5626846462680035e-309",0), strtod("7.9050503334599447e-323",0) );
printf("%d\n", (int) errno);
return 0;
}
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!