0

I'm trying a really simple program and I don't undersand an apparent loss of precision when an int is converted into a double.

void collinear(int x1, int y1, int x2,  
               int y2, int x3, int y3) 
{ 
 
    int a = (x1 * (y2 - y3)) +  
            (x2 * (y3 - y1)) +  
            (x3 * (y1 - y2)); 
  
    if (a == 0) 
        cout << "Yes"; 
    else
        cout << "No"; 
} 

This is the version with a double

void collinear(double x1, double y1, double x2,  
               double y2, double x3, double y3) 
{ 

    double a = (x1 * (y2 - y3)) +  
            (x2 * (y3 - y1)) +  
            (x3 * (y1 - y2)); 
  
    if (a == 0.0) 
        cout << "Yes"; 
    else
        cout << "No"; 
} 

Given this input the two programs behave diffeently and I don't understand why

collinear(0,0,94911150,94911151,94911151,94911152); 

Program with doubles: Yes

Program with ints: No


The answer when worked out with pure math is also No. Is the program with the doubles losing precision?

cjds
  • 8,268
  • 10
  • 49
  • 84
  • 1
    It's not the conversion (your integers are too small for that) its the multiplication . E.g. `94911150` is 27 bits. Two of those integers multipled together is 54 bits. Typical double has 53 bits of precision. It's almost as if those numbers have been chosen deliberately. – john Nov 15 '20 at 08:22
  • 1
    A typical `double` is represented using 64 bits, and converting an integral value with (about - it depends on the details of the representation) 15 significant decimal digits to a `double` typically does not lose precision. However, a series of subtractions and multiplications done on such floating point values can lose precision. One way to increase chances of losing precision is to subtract two large floating point values. Another is to multiply a large value by the results of such a subtraction. Your calculation of `a` does such a series of operations. – Peter Nov 15 '20 at 08:24

0 Answers0