This is not a duplicate of the famous Is floating point math broken, even if it looks like one at first sight.
I'm reading a double
from a text file using fscanf(file, "%lf", &value);
and comparing it with the ==
operator against a double literal. If the string is the same as the literal, will the comparision using ==
be true
in all cases?
Example
Text file content:
7.7
Code snippet:
double value; fscanf(file, "%lf", &value); // reading "7.7" from file into value if (value == 7.7) printf("strictly equal\n");
The expected and actual output is
strictly equal
But this supposes that the compiler converts the double literal 7.7
into a double exactly the same way as does the fscanf
function, but the compiler may or may not use the same library for converting strings to double.
Or asked otherwise: does the conversion from string to double result in a unique binary representation or may there be slight implementation dependent differences?
Live demonstration
To compare two floating point or double values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.
We can convert float to a string easily using str() function.
In the case of floating-point numbers, the relational operator (==) does not produce correct output, this is due to the internal precision errors in rounding up floating-point numbers. In the above example, we can see the inaccuracy in comparing two floating-point numbers using “==” operator.
From the c++ standard:
[lex.fcon]
... If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner...
emphasis mine.
So you can only rely on equality if the value is strictly representable by a double.
About C++, from cppreference one can read:
[lex.fcon]
(§6.4.4.2)
The result of evaluating a floating constant 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 (in other words, default rounding direction during translation is implementation-defined).
Since the representation of a floating literal is unspecified, I guess you cannot conclude about its comparison with a scanf
result.
About C11 (standard ISO/IEC 9899:2011):
[lex.fcon]
(§6.4.4.2)
Recommended practice
7 The translation-time conversion of floating constants should match the execution-time conversion of character strings by library functions, such as
strtod
, given matching inputs suitable for both conversions, the same result format, and default execution-time rounding.
So clearly for C11, this is not guaranteed to match.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With