Java vs C floating point: "x * x" differs from "pow(x,2)"?
c, floating-accuracy, floating-point, java
Solution
As pst and trutheality have already wisely noted, C is promoting the `float` to a `double` before the multiplication. Actually, they are promoted to an 80-bit extended precision value when they are pushed onto the stack. Here is the assembler output (VS2005 x86 C89)
double b = a * a;
00411397 fld dword ptr [a]
0041139A fmul dword ptr [a]
0041139D fstp qword ptr [b]
The FLD Instruction
The FLD instruction loads a 32 bit, 64 bit, or 80 bit floating point value onto the stack. This instruction converts 32 and 64 bit operands to an 80 bit extended precision value before pushing the value onto the floating point stack.
Interestingly, if I build to target x64, the `movss` instruction is used and you get a value of `0.779281497001648` as the result, i.e., what you are seeing in your java example. Give it a try.
Problem
Why is this true? Java appears to produce a result with a small discrepancy when multiplying two floats compared to C and even the Java Math.pow method. Java: ``` float a = 0.88276923; double b = a * a; // b becomes 0.779281497001648 <---- what??? b = Math.pow(a,2); // b becomes 0.7792815081874238 ``` C: ``` float a = 0.88276923; double b = a * a; // b becomes 0.7792815081874238 pow(a,2); // b becomes 0.7792815081874238 ``` Update: Per Ed S.'s comment, I have also found that the C behavior changes depending on the compiler. Using gcc it appears to match the Java behavior. Using visual studio (depending on your target platform) it can produce the results seen above or those seen in Java. Ugh.