marmistrz
marmistrz

Reputation: 6414

Is stof, strtof deterministic?

I'm reading floats from a string. They can be written in a various form, so

float f1 = strtof("999999999999.16");
float f2 = stof("000999999999999.1600000");
assert(f1 == f2);

Can I be sure that the assertion will be always true, no matter of leading and trailing zeros? The separator will be always a dot, stof doesn't handle the comma.

Upvotes: 3

Views: 1588

Answers (2)

Simon Byrne
Simon Byrne

Reputation: 7874

The C++ 14 (§21.5) standard states that:

float stof(const string& str, size_t* idx = 0);

double stod(const string& str, size_t* idx = 0);

long double stold(const string& str, size_t* idx = 0);

Effects: the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold( str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

In many cases therefore they will be the same, but the intermediate double does open the potential for double rounding. E.g. if str = "1.0000000596046448", then the closest float (assuming IEEE754 arithmetic) is 1.0000001f, whereas the closest double is exactly halfway between 1.0f and 1.0000001f, and so subsequent conversion to float will round down to 1.0f.

That's the theory at least. In practice, however, I am unable to recreate this: http://ideone.com/NMRy14

Upvotes: 1

mindriot
mindriot

Reputation: 5678

The C11 standard, in 7.22.1.3p9, has this to say about C's strtof/strtod/strtold (which should be what the C++ versions use underneath, at least judging from cppreference):

If the subject sequence has the decimal form and at most DECIMAL_DIG (defined in <float.h>) significant digits, the result should be correctly rounded.

Given that both of your code lines have the same number of significant digits, they should behave the same. But this is merely conjecture based on the fact that the standard mentions “significant digits” here at all; it is not mentioned anywhere else, and the standard does not say anything more explicit regarding leading (before the decimal point) or trailing (after the decimal point) zeroes.

Upvotes: 3

Related Questions