Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the "char-sequence" argument to NaN generating functions for?

Tags:

c

nan

standards

c99

Aside from the NAN macro, C99 has two ways to generate a NaN value for a floating point number, the nanf(const char *tagp) function and strtof("NAN(char-sequence)").

Both of these methods of generating a NaN take an optional string argument (*tagp in nanf() and the char-sequence in the strtof method). What exactly does this string argument do? I haven't been able to find any concrete examples of how you'd use it. From cppreference.com we have:

The call nan("string") is equivalent to the call strtod("NAN(string)", (char**)NULL);

The call nan("") is equivalent to the call strtod("NAN()", (char**)NULL);

The call nan(NULL) is equivalent to the call strtod("NAN", (char**)NULL);

And nan(3) says:

These functions return a representation (determined by tagp) of a quiet NaN. [snip] The argument tagp is used in an unspecified manner. On IEEE 754 systems, there are many representations of NaN, and tagp selects one.

This doesn't really tell me what I can use for the tagp string or why I'd ever want to use it. Is there a list anywhere of the valid options for this tag string, and what would the reason be to use one over the default nanf(NULL)?

like image 928
mshildt Avatar asked May 06 '15 20:05

mshildt


2 Answers

Tl;Dr : tagp argument gives you the ability to have different NAN values.

This is from man page for nan(3) which gives a little more information on tagp.

Mainly:

The nan() functions return a quiet NaN, whose trailing fraction field contains the result of converting tagp to an unsigned integer.

This gives you the ability to have different NAN values.

Specifically from the C99 Rationale doc:

Other applications of NaNs may prove useful. Available parts of NaNs have been used to encode auxiliary information, for example about the NaN’s origin. Signaling NaNs might be candidates for filling uninitialized storage; and their available parts could distinguish uninitialized floating objects. IEC 60559 signaling NaNs and trap handlers potentially provide hooks for maintaining diagnostic information or for implementing special arithmetics.

There is an implementation of it here. Mind you, this may or may not be standard conforming, as noted in comments. However, it should give you an idea of what tagp is used for.

As in the man page, you can see the replacement mentioned above:

nan("1") = nan (7ff8000000000001)
nan("2") = nan (7ff8000000000002)

Full man page here:

NAN(3) BSD Library Functions Manual
NAN(3)

NAME nan -- generate a quiet NaN

SYNOPSIS #include

 double
 nan(const char *tagp);

 long double
 nanl(const char *tagp);

 float
 nanf(const char *tagp);

DESCRIPTION The nan() functions return a quiet NaN, whose trailing fraction field contains the result of converting tagp to an unsigned integer. If tagp is too large to be contained in the trailing fraction field of the NaN, then the least significant bits of the integer represented by tagp are used.

SPECIAL VALUES If tagp contains any non-numeric characters, the function returns a NaN whos trailing fraction field is zero.

If tagp is empty, the function returns a NaN whos trailing fraction field is zero.

STANDARDS The nan() functions conform to ISO/IEC 9899:2011.

BSD July 01, 2008

like image 126
bentank Avatar answered Oct 05 '22 15:10

bentank


This doesn't really tell me what I can use for the tagp string or why I'd ever want to use it.

Some floating point standards, e.g., IEEE-754, have multiple different NaN values. This nan function specification allows an implementation to select a specific NaN representation depending on the string on a way that might be specified by the implementation.

like image 36
ouah Avatar answered Oct 05 '22 13:10

ouah