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!