rwallace
rwallace

Reputation: 33405

strtof = strtod followed by cast?

Suppose you have a string like "0.1" that can be only approximately represented as a binary floating point number, and you want to convert it to single precision floating point. This can be done as

strtof(s, 0);

or

(float)strtod(s, 0);

Intuitively, these should give the same result, but is intuition correct in all cases? Or are there any edge cases in which the second form, by doing the rounding twice, gives a slightly different result from the first form?

Upvotes: 7

Views: 561

Answers (2)

Pascal Cuoq
Pascal Cuoq

Reputation: 80305

The C standard's specification of strtod and strtof is underspecified. It leaves room for the possibility that strtof returns (float)strtod always, very often or never. (This paragraph refers to another section of the standard that contains that paragraph, which says “the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner”).

The typical implementations of strtod and strtof return respectively the nearest double and the nearest float to the decimal representation passed to them. When these functions behave this way, then strtof(s, 0) is almost always identical to (float)strtod(s, 0). The decimal representations for which they are not identical are said to exhibit a double-rounding problem, because rounding the decimal representation first to double and then to float produces a different result than rounding directly to float. Note that when this happens, the strtof result is the more exact one. The intermediate rounding made the error slightly more than half a ULP rather than slightly less than half a ULP.

One example of decimal representation with a double-rounding problem when going through double before converting to float is 1.01161128282547 (taken from this quiz). The nearest double is exactly halfway between two floats. Rounding directly to float gets you the nearest float, and going through the nearest double produces the other float.

Upvotes: 6

nonForgivingJesus
nonForgivingJesus

Reputation: 593

x86 FPU always works with 80-bit float numbers no matter with what types you operate. There even can be extra runtime cost in convertation from double to float.

I'm not sure, but strtof() can be implemented as wrapper around strtod(), so in your place i'd better use strtof(), instead calling function for parsing into double and then casting to float, to indicate your intentions. If you do not trust compiler and want optmize code, then maybe use of (float)strtod() will save you a bit performance on extra call/ret instructions.

Upvotes: -1

Related Questions