C++ Floating point errors in a loop vs in a single expression

Viewed 75

(Disclaimer: I understand that floats can't represent tenths precisely.)

I was messing around in C++ with single-precision floats (to test out rounding errors), and I came across this weird behavior.

#include <iostream>
#include <iomanip>
using namespace std;

int main(){
  // set number of sigdigs in output
  cout << setprecision(9);

  float singleA = 0.1 * 7.;
  float singleB = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1;
  float singleC = 0.0;
  for (int i = 0; i < 7; i++){
    singleC += 0.1;
  }
  // ^ i expected that to be the same as
  // 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1

  cout << "multiplied:      " << singleA << endl;
  cout << "added in one go: " << singleB << endl;
  cout << "added in a loop: " << singleC << endl;
  return 0;
}

Output:

multiplied:      0.699999988
added in one go: 0.699999988
added in a loop: 0.700000048

I was wondering why adding 0.1 7 times in an expression results in a different result than adding 0.1 7 times in a loop. I'm both adding 0.1 7 times, so why does this happen? Does singleB get optimized using floating decimal arithmetic?

1 Answers

0.1 is a double, not a float. So when you add seven of them in an expression, the operations are carried out using double-precision arithmetic and then the final result is converted to single precision. In the loop, you discard the extra precision after each addition. Try it with 0.1f and you’ll get identical results.

Related