Fundamentals of C: a double variable not equal to a double expression?

I work with an array of doubles called indata (on the heap allocated by malloc) and a local double name sum .

I wrote two different functions for comparing values ​​in indata and got different results. In the end, I decided that the discrepancy is due to one function that uses the expression in the conditional test, and the other function uses the local variable in the same conditional test. I expected them to be equivalent.

My function A uses:

  if (indata[i]+indata[j] > max) hi++; 

and my function B uses:

  sum = indata[i]+indata[j]; if (sum>max) hi++; 

After going through the same dataset and max , I get different hi values ​​depending on the function used. I believe that function B is correct, and function A is misleading. Similarly, when I try the snippet below

  sum = indata[i]+indata[j]; if ((indata[i]+indata[j]) != sum) etc. 

that the conditional value will be true.

Although I understand that floating point numbers do not necessarily provide an accurate representation, why does this exact representation change when evaluated as a vs expression stored in a variable? Is it best to use a double expression like this before the conditional? Thank you

+8
c syntax floating-point floating-accuracy expression
source share
1 answer

I suspect you are using 32-bit x86, the only common architecture is prone to excessive accuracy. In C, expressions like float and double actually evaluated as float_t or double_t , whose relationships with float and double are reflected in the macro FLT_EVAL_METHOD . In the case of x86, both are defined as long double , because fpu is actually not capable of performing arithmetic with single or double precision. (It has mode bits designed for this, but the behavior is a bit erroneous and therefore cannot be used.)

Assigning an object of type float or double is one of the ways to force rounding and get rid of excessive precision, but you can also just add a gratuitous translation to (double) if you prefer to leave it as an expression without assignments.

Note that forced rounding to the desired accuracy is not equivalent to performing arithmetic with the required accuracy; instead of one rounding step (during arithmetic) you now have two (during arithmetic and again to remove unwanted accuracy), and in cases where the first rounding gives the exact middle, the second rounding can go in the “wrong” direction. This question is usually called double rounding, and it makes excess accuracy significantly worse than the nominal accuracy for certain types of calculations.

+12
source share

All Articles