Add documentation and tests for strtod changes.

This commit is contained in:
Stephen Heumann 2023-06-08 19:10:09 -05:00
parent 509f09253f
commit e5c69670cd
3 changed files with 129 additions and 9 deletions

View File

@ -27,6 +27,7 @@
{1} c99inline.c
{1} c99desinit.c
{1} c99printfa.c
{1} c99strtold.c
{1} c11generic.c
{1} c11align.c
{1} c11noret.c

View File

@ -0,0 +1,113 @@
/*
* Test strtold function (C99).
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
void fail(void) {
printf ("Failed Conformance Test c99strtold\n");
exit(0);
}
void test(const char *str, long double val, size_t len, int err) {
char *endptr;
long double result;
errno = 0;
result = strtold(str, &endptr);
if (err >= 0 && errno != err)
fail();
if (endptr-str != len)
fail();
if (!isnan(val)) {
if (result != val || !!signbit(result) != !!signbit(val))
fail();
} else {
if (!isnan(result))
fail();
}
}
int main(void) {
test("1", 1.0L, 1, 0);
test("-2.25E-7", -2.25E-7L, 8, 0);
test("InfiniTy", +INFINITY, 8, 0);
test("-inFinitx", -INFINITY, 4, 0);
test("NaN", NAN, 3, 0);
test(" -nan(123)", NAN, 10, 0);
test("nan(abC_123)", NAN, 12, 0);
test("nan(abC_123-)", NAN, 3, 0);
test("nan(123", NAN, 3, 0);
test("\t+Nan()", NAN, 7, 0);
test("-0xF.8p-1", -7.75L, 9, 0);
test(" +0XAB4fp2", 175420.0L, 10, 0);
test("0X.23423p-1", 0X.23423p-1L, 11, 0);
test("0x4353.p+7", 2206080.0L, 10, 0);
test("0xabcdef0012345678ffffffffffffp123",
3.7054705751091077761e+70L, 34, 0);
test("0xabcdef0012345678000000000000p123",
3.7054705751091077758e+70L, 34, 0);
test("0x0.0000000000000000000000012345aP50",
1.61688425235478883124e-14L, 36, 0);
test("0x1324124.abcd23p-3000", 1.63145601325652579262e-896L, 22, 0);
test("0x0000000000.000000p1234567890123456789012345678901234567890",
0.0, 60, 0);
test("0X1p17000", INFINITY, 9, ERANGE);
test("0x1.fffffffffffffffep16383",
1.18973149535723176502e+4932L, 26, 0);
test("0x1.ffffffffffffffffp16383", INFINITY, 26, ERANGE);
test("0X1p-16400L", 1.28254056667789211512e-4937L, 10, -1);
test("0x3abd.232323p-16390", 1.97485962609712244075e-4930L, 20, 0);
test("0x7.7p-17000", 0.0, 12, -1);
test("+0x1.8p+", 1.5L, 6, 0);
test(" \t\f\n\r\v1.25---", 1.25, 10, 0);
test("0x.p50", 0.0, 1, 0);
test(" +abc", 0.0, 0, -1);
test("-0", -0.0, 2, 0);
test("-0x0p123", -0.0, 8, 0);
fesetround(FE_UPWARD);
test("0x8.0000000000000008", 0x8.000000000000001p0L, 20, 0);
test("0x8.0000000000000009", 0x8.000000000000001p0L, 20, 0);
test("0x8.0000000000000018", 0x8.000000000000002p0L, 20, 0);
test("-0x8.0000000000000008", -0x8.000000000000000p0L, 21, 0);
test("-0x8.0000000000000009", -0x8.000000000000000p0L, 21, 0);
test("-0x8.0000000000000018", -0x8.000000000000001p0L, 21, 0);
test("0x8.00000000000000080001", 0x8.000000000000001p0L, 24, 0);
fesetround(FE_DOWNWARD);
test("0x8.0000000000000008", 0x8.000000000000000p0L, 20, 0);
test("0x8.0000000000000009", 0x8.000000000000000p0L, 20, 0);
test("0x8.0000000000000018", 0x8.000000000000001p0L, 20, 0);
test("-0x8.0000000000000008", -0x8.000000000000001p0L, 21, 0);
test("-0x8.0000000000000009", -0x8.000000000000001p0L, 21, 0);
test("-0x8.0000000000000018", -0x8.000000000000002p0L, 21, 0);
test("0x8.00000000000000080001", 0x8.000000000000000p0L, 24, 0);
fesetround(FE_TOWARDZERO);
test("0x8.0000000000000008", 0x8.000000000000000p0L, 20, 0);
test("0x8.0000000000000009", 0x8.000000000000000p0L, 20, 0);
test("0x8.0000000000000018", 0x8.000000000000001p0L, 20, 0);
test("-0x8.0000000000000008", -0x8.000000000000000p0L, 21, 0);
test("-0x8.0000000000000009", -0x8.000000000000000p0L, 21, 0);
test("-0x8.0000000000000018", -0x8.000000000000001p0L, 21, 0);
test("0x8.00000000000000080001", 0x8.000000000000000p0L, 24, 0);
fesetround(FE_TONEAREST);
test("0x8.0000000000000008", 0x8.000000000000000p0L, 20, 0);
test("0x8.0000000000000009", 0x8.000000000000001p0L, 20, 0);
test("0x8.0000000000000018", 0x8.000000000000002p0L, 20, 0);
test("-0x8.0000000000000008", -0x8.000000000000000p0L, 21, 0);
test("-0x8.0000000000000009", -0x8.000000000000001p0L, 21, 0);
test("-0x8.0000000000000018", -0x8.000000000000002p0L, 21, 0);
test("0x8.00000000000000080001", 0x8.000000000000001p0L, 24, 0);
printf ("Passed Conformance Test c99strtold\n");
return 0;
}

View File

@ -557,7 +557,7 @@ Generic selection expressions are primarily useful within macros, which can give
24. (C99) Floating-point constants may now be expressed in a hexadecimal format. These consist of a leading 0X or 0x, followed by a sequence of hexadecimal digits optionally containing a period, then P or p, then an exponent expressed as a sequence of decimal digits optionally preceded by + or -. These designate the number given by the hexadecimal digit sequence (with any digits after the period being the fractional part) multiplied by 2 raised to the specified exponent. For example, the constant 0xF.8p-1 is equivalent to 7.75.
Note that the fprintf family of functions also support output in this hexadecimal floating-point format using the 'A' and 'a' conversion specifiers, described below. However, the hexadecimal floating-point format is currently not supported as an input format for any library functions.
Note that the fprintf family of functions also support output in this hexadecimal floating-point format using the 'A' and 'a' conversion specifiers, described below. The strtod, strtold, and strtof functions can also accept numbers in this format as input.
25. (C99) When a function parameter is declared with an array type, type qualifiers and/or the keyword "static" may be included within the angle brackets that designate the array type. For example, a function may be defined as:
@ -1423,14 +1423,6 @@ long double tanhl(long double x);
These functions are equivalent to the existing un-suffixed versions, apart from their argument and return types. In ORCA/C, most of them actually behave identically to the un-suffixed versions. An exception is the modf family of functions, which differ in the type of the location in which the integer part of the value is stored.
Similarly, there are float and long double analogs of the string conversion function strtod:
#include <stdlib.h>
float strtof(const char * restrict str, char ** restrict ptr);
long double strtold(const char * restrict str, char ** restrict ptr);
As currently implemented in ORCA/C, strtof and strtold behave identically to strtod, all giving values with the precision and range of long double.
20. Several <time.h> functions can now use the Time Tool Set by Geoff Weiss to determine the time zone. This behavior is controlled by a new variable:
#include <time.h>
@ -1461,6 +1453,18 @@ The only time base supported by ORCA/C is TIME_UTC. This gives the time in seco
Although struct timespec can represent a time with nanosecond resolution, ORCA/C currently only reports the time with a resolution of one second, so ts->tv_nsec is always set to 0.
22. (C99) The strtod function can now accept strings in a hexadecimal floating-point format, in addition to the normal decimal format. The hexadecimal format consists of an optional leading + or - sign, then 0X or 0x, then a sequence of hexadecimal digits optionally containing a period, then an optional exponent part consisting of a P or p character followed by a decimal number optionally preceded by + or -. A string in this format designates the number given by the sign (if present) and the hexadecimal digit sequence (with any digits after the period being the fractional part) multiplied by 2 raised to the specified exponent (if it is present). For example, "0xF.8p-1" designates the number 7.75.
The strtod function also accepts the string "INFINITY" (without regard to case, and optionally preceded by + or -) to designate an infinity. This is equivalent to the string "INF", which was already accepted in earlier versions of ORCA/C.
Also, there are now float and long double analogs of the strtod function:
#include <stdlib.h>
float strtof(const char * restrict str, char ** restrict ptr);
long double strtold(const char * restrict str, char ** restrict ptr);
As currently implemented in ORCA/C, strtof and strtold behave identically to strtod, all giving values with the precision and range of long double.
-- Compiler changes introduced in C 2.1.0 -----------------------------------
The Default .h File
@ -2205,6 +2209,8 @@ int foo(int[42]);
(Devin Reade)
254. The strtod() function should be able to skip over line feed, form feed, carriage return, and vertical tab characters (as well as space and horizontal tab) as part of the whitespace that may precede the number.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.