When you're using double
you are invoking what is called "Floating Point Arithmetics". In practice, this is an imprecise way to represent numbers, simply because not every real number can be precisely represented in a finite number of bits.
As a result, some numbers, for instance, can never be represented precisely, and instead of "25" your computer (not the compiler), has a result of, say, 25.00000000000071 - close enough for all practical purposes, but clearly not equal to 25.
There are few other quirks related to IEEE-754 floating point - adding 0.1 ten times to 0.0 doesn't necessarily reach 1.0, etc.
Which is why, in practice, you should never compare for equality, but you should compare whether the absolute value of the difference between two numbers is smaller than an (small, but large enough) epsilon.
const double espilon = 0.00000001
if (fabs(x - y) < epsilon) {
// Assume approximately equal
}
A good (MATLAB based, but the concepts apply throughout everything that uses IEEE-754, nowadays, that means about everywhere) introduction to what is going on is here:
https://www2.bc.edu/~quillen/sp11/mt414/pres/floatarith.pdf
Also, pow()
is not the most reasonable way to do squares - pow(x, m)
internally computes exp(m log(x))
in order to handle arbitrary real-number bases and exponents. This particular conversion is exactly why it looses precision.
This also means pow()
is ridiculously slow when compared with multiplication-based approach.