Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing floating point values converted from strings with literals

Tags:

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

like image 817
Jabberwocky Avatar asked Oct 18 '17 12:10

Jabberwocky


People also ask

What is a better way to compare floating point values?

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.

Which function converts float data to string?

We can convert float to a string easily using str() function.

Why is it a problem to compare two floating point numbers?

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.


2 Answers

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.

like image 181
Richard Hodges Avatar answered Sep 22 '22 10:09

Richard Hodges


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.

like image 27
YSC Avatar answered Sep 22 '22 10:09

YSC