Consider two following pieces of code – the only difference between them is a single cout which prints the value eps:
http://ideone.com/0bEeHz – here the program enters and infinite loop since after the cout eps changes value to 0
#include <iostream>
int main()
{
double tmp = 1.;
double eps;
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
std::cout << "eps before: " << eps;
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
while(eps < 1.) {
tmp = eps;
eps *= 2.;
if(tmp == eps) {
printf("wtf?\n");
}
}
std::cout << "eps after: " << eps;
}
http://ideone.com/pI4d30 – here I’ve commented out the cout.
#include <iostream>
int main()
{
double tmp = 1.;
double eps;
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
//std::cout << "eps before: " << eps;
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
while(eps < 1.) {
tmp = eps;
eps *= 2.;
if(tmp == eps) {
printf("wtf?\n");
}
}
std::cout << "eps after: " << eps;
}
Hence, one single cout changes program logic dramatically and very surprisingly. Why is that?
I think it’s a case of Section 5 (Expressions), paragraph 11
at work, cf. this variation of the original code.
Calculations and comparisons performed at extended precision. The loop runs until
epsis the smallest positive extended value (probably the 80-bit x87 extended type).Still at extended precision,
eps != 0For the conversion to a string to print,
epsis stored and converted todoubleprecision, resulting in 0.Yes, now it is.