CSC231 Unexpected Floating-Point Results

From dftwiki3
Jump to: navigation, search

--D. Thiebaut 10:50, 11 December 2012 (EST)


Here are some examples of programs that generate unexpected results due to the way Floating Point numbers are treated by the compiler/processor.
Two java programs computing 77777.0 / 7.0 and 77777.0 * ( 1/7.0 ) yield incorrect results, both with floats and with doubles, while the C++ program using doubles yields the correct expected result.





Example 1, Java


Source


// taken from http://www.lahey.com/float.htm

class FloatingPointStrange3 {
   
    
    public static void main( String args[] ) {
	float x, y, y1, z, z1;

	x = 77777.0f; 
	y = 7.0f;
	y1 = 1.0f / y;   //  1/7
	z = x / y;    // 77777 / 7 = 11111
	z1 = x * y1;  // 77777 * 1 / 7 = 11111
	
	if ( z != z1 ) {
	    System.out.println( String.format( "%1.3f != %1.3f", z, z1 ) );
	    System.out.println( String.format( "%1.30f != %1.30f", z, z1 ) );
	}
	else {
	    System.out.println( String.format( "%1.3f == %1.3f", z, z1 ) );
	    System.out.println( String.format( "%1.30f == %1.30f", z, z1 ) );
	}
			    
    }
}

Output with Floats


javac FloatingPointStrange3.java
java FloatingPointStrange3

11111.000 != 11111.001
11111.000000000000000000000000000000 != 11111.000976562500000000000000000000


Output with Doubles

If we replace float by double in the program and leave the remaining program the same, we get:


javac FloatingPointStrange3.java
java FloatingPointStrange3
11111.000 == 11111.000
11111.000000000000000000000000000000 == 11111.000000000000000000000000000000

Example 2, C++ and Floats

The same program in C++:

Source


// taken from http://www.lahey.com/float.htm
#include <iostream>
#include <stdio.h>
using namespace std;

int main( int argc, char *argv[] ) {
  float x = 77777.0;
  float y = 7.0;
  float y1 = 1.0 / y;    // 1/7
  float z = x / y;       // 77777 / 7 = 11111
  float z1 = x * y1;     // 77777 * 1/7 = 11111
  
  if ( z != z1 ) {
    cout << z << " != " << z1 << endl;
    printf( "%1.20f != %1.20f\n", z, z1 );
  }
  else {
    cout << z << " == " << z1 << endl;
    printf( "%1.20f == %1.20f\n", z, z1 );
  }

  return 0;
}


Output

g++ FloatingPointStrange3.cpp
a.out
11111 != 11111
11111.00000000000000000000 != 11111.00097656250000000000


Example 3, C++ and Doubles

Source, using doubles


// taken from http://www.lahey.com/float.htm
#include <iostream>
#include <stdio.h>
using namespace std;

int main( int argc, char *argv[] ) {
  double x = 77777.0;
  double y = 7.0;
  double y1 = 1.0 / y;    // 1/7
  double z = x / y;       // 77777 / 7 = 11111
  double z1 = x * y1;     // 77777 * 1/7 = 11111
  
  if ( z != z1 ) {
    cout << z << " != " << z1 << endl;
    printf( "%1.20f != %1.20f\n", z, z1 );
  }
  else {
    cout << z << " == " << z1 << endl;
    printf( "%1.20f == %1.20f\n", z, z1 );
  }

  return 0;
}


Output

g++ FloatingPointStrange3.cpp
./a.out
11111 == 11111
11111.00000000000000000000 == 11111.00000000000000000000