   Calculation result inconsistent
  I am not seeing where during the casting or other process that would make A and B different in this code snippet:    float planeD = -529.99994;//Ray plane intersection with plane normal's y and z component 0float nx = n.x();float p0x = p0.x();float d0x = d0.x();float A = ( -nx*p0x + planeD ) / (nx*d0x);float temp4 = -nx*p0x;float temp5 = temp4 + planeD;float temp6 = nx*d0x;float B = temp5 / temp6;For example, in Visual Studio with the values:d0x0.96720123floatnx-0.99999994floatp0x-719.93292floatI get A1292.3193floatB1292.3195floatIs any intermediate calculation done in double before converted back to float?Thanks   
  Debug or Release build?Have you checked the assembly?my guess?( -nx*p0x + planeD ) / (nx*d0x)stays in the FP registers for the entire calculation, and thus the whole calculation is done at a high resolution. (iirc, on x86 it is 80bit numbers independent of the source being float or double)float temp4 = -nx*p0x;float temp5 = temp4 + planeD;float temp6 = nx*d0x;float B = temp5 / temp6;on the other hand, might be storing each "temp" out of the FP registers, thus resulting in a lower precision calculation.   ;Quote:Is any intermediate calculation done in double before converted back to floatPossibly. Depends on CPU and compiler.And even without that, floating point representations are not accurate.This means that if operations are applied in different order, the results will differ. There are even some extreme cases with flags where same code can produce different results for same inputs.   ;  Debug. Here is the disassembly that would take me a while to decipher. Surely it hides the secret. =)This is a Intel Core 2 Extreme CPU Q6850 running VS2008 9.0.21022.8 RTM.float nx = n.x();63F75804  lea    ecx,[n] 63F7580A  call   Lib::Vector::x (63CB83B2h) 63F7580F  fstp   dword ptr [nx] float p0x = p0.x();63F75815  lea    ecx,[p0] 63F7581B  call   Lib::Vector::x (63CB83B2h) 63F75820  fstp   dword ptr [p0x] float d0x = d0.x();63F75826  lea    ecx,[d0] 63F7582C  call   Lib::Vector::x (63CB83B2h) 63F75831  fstp   dword ptr [d0x] float A = ( -nx*p0x + planeD ) / (nx*d0x);63F75837  fld    dword ptr [nx] 63F7583D  fchs   63F7583F  fmul   dword ptr [p0x] 63F75845  fadd   dword ptr [planeD] 63F7584B  fld    dword ptr [nx] 63F75851  fmul   dword ptr [d0x] 63F75857  fdivp  st(1),st 63F75859  fstp   dword ptr [A] float temp4 = -nx*p0x;63F7585F  fld    dword ptr [nx] 63F75865  fchs   63F75867  fmul   dword ptr [p0x] 63F7586D  fstp   dword ptr [temp4] float temp5 = temp4 + planeD;63F75873  fld    dword ptr [temp4] 63F75879  fadd   dword ptr [planeD] 63F7587F  fstp   dword ptr [temp5] float temp6 = nx*d0x;63F75885  fld    dword ptr [nx] 63F7588B  fmul   dword ptr [d0x] 63F75891  fstp   dword ptr [temp6] float B = temp5 / temp6;63F75897  fld    dword ptr [temp5] 63F7589D  fdiv   dword ptr [temp6] 63F758A3  fstp   dword ptr  Quote:Original post by KulSeranDebug or Release build?Have you checked the assembly?my guess?( -nx*p0x + planeD ) / (nx*d0x)stays in the FP registers for the entire calculation, and thus the whole calculation is done at a high resolution. (iirc, on x86 it is 80bit numbers independent of the source being float or double)float temp4 = -nx*p0x;float temp5 = temp4 + planeD;float temp6 = nx*d0x;float B = temp5 / temp6;on the other hand, might be storing each "temp" out of the FP registers, thus resulting in a lower precision calculation.;Quote:float nx = n.x();63F75804 lea ecx,[n]63F7580A call Lib::Vector::x (63CB83B2h)63F7580F fstp dword ptr [nx]float p0x = p0.x();63F75815 lea ecx,[p0]63F7581B call Lib::Vector::x (63CB83B2h)63F75820 fstp dword ptr [p0x]float d0x = d0.x();63F75826 lea ecx,[d0]63F7582C call Lib::Vector::x (63CB83B2h)63F75831 fstp dword ptr [d0x]float A = ( -nx*p0x + planeD ) / (nx*d0x);63F75837 fld dword ptr [nx]63F7583D fchs63F7583F fmul dword ptr [p0x]63F75845 fadd dword ptr [planeD]63F7584B fld dword ptr [nx]63F75851 fmul dword ptr [d0x]63F75857 fdivp st(1),st63F75859 fstp dword ptr [A]float temp4 = -nx*p0x;63F7585F fld dword ptr [nx]63F75865 fchs63F75867 fmul dword ptr [p0x]63F7586D fstp dword ptr [temp4]float temp5 = temp4 + planeD;63F75873 fld dword ptr [temp4]63F75879 fadd dword ptr [planeD]63F7587F fstp dword ptr [temp5]float temp6 = nx*d0x;63F75885 fld dword ptr [nx]63F7588B fmul dword ptr [d0x]63F75891 fstp dword ptr [temp6]float B = temp5 / temp6;63F75897 fld dword ptr [temp5]63F7589D fdiv dword ptr [temp6]63F758A3 fstp dword ptr  Notice, the bolded area on top? all the calculations are done in the FP registers (no fstp instructions) only loading (fld) in new values as needed.Read the bottom one. Every substep is load (fld) operator then store (fstp). Resulting in a loss of precision in the second case.But, before you go running off thinking that there is a problem. Try it in release.  The debug version is going to be more explicit about following your every line of code, because it needs to make sure you can see every variable in the debugger's watch window if you want.  In the release version, it should optimize out all those temp variables, and end up with the same code and same results.;  No matter what, the numbers it gave you are accurate to 7 significant digits, which is roughly the guarantee made by the 32bit IEEE float representation. So as far as you should be concerned, both outputs are 100% correct.   ;  Thanks. I enabled debug information for release, and made sure optimization is not off (It is currently blank selection wise and I assume that means it is on), and now the dissassembly is below. I added a line if(A!=B) i=0. I think this should be valid in testing that these two numbers have the exact same bit patterns, indicative that the same process was used to calculate the two.The result is I can break at the line i=0. And the disassembly still has many fstp for B. Am I doing anything incorrect in having arrived at this result?float p0x = p0.x();float d0x = d0.x();float A = ( -nx*p0x + planeD ) / (nx*d0x);63FDFD31  fld    dword ptr [esp+0B8h] 63FDFD38  fld    dword ptr [esp+0D0h] 63FDFD3F  fld    st(0) 63FDFD41  fmulp  st(2),st float temp4 = -nx*p0x;float temp5 = temp4 + planeD;float temp6 = nx*d0x;float B = temp5 / temp6;if( A != B )63FDFD43  fld    dword ptr [esp+0ACh] 63FDFD4A  fld    st(0) 63FDFD4C  fmul   st,st(2) 63FDFD4E  fsubr  qword ptr [__real@c0808fffe0000000 (64023948h)] 63FDFD54  fdiv   st,st(3) 63FDFD56  fstp   dword ptr [esp+1Ch] 63FDFD5A  fld    dword ptr [esp+1Ch] 63FDFD5E  fxch   st(2) 63FDFD60  fchs   63FDFD62  fmulp  st(1),st 63FDFD64  fstp   dword ptr [esp+1Ch] 63FDFD68  fld    dword ptr [esp+1Ch] 63FDFD6C  fsub   qword ptr [__real@40808fffe0000000 (64023940h)] 63FDFD72  fstp   dword ptr [esp+1Ch] 63FDFD76  fld    dword ptr [esp+1Ch] 63FDFD7A  fxch   st(2) 63FDFD7C  fstp   dword ptr [esp+1Ch] 63FDFD80  fld    dword ptr [esp+1Ch] 63FDFD84  fdivp  st(2),st 63FDFD86  fxch   st(1) 63FDFD88  fstp   dword ptr [esp+1Ch] 63FDFD8C  fld    dword ptr [esp+1Ch] 63FDFD90  fucompp63FDFD92  fnstsw ax   63FDFD94  test   ah,44h 63FDFD97  jnp    Lib::geometry::function+2BBh (63FDFD9Bh) i=0;63FDFD99  xor    ebx,ebx   ;  Visual Studio has 3 floating point modes: precise, strict and fast. Precise mode is the default, and it disables optimisations that can change floating point values. It also performs rounding on the values, but I'm not seeing any of those instructions in your assembly, so maybe you're using Fast mode instead?FP:Fast produces different results in release mode due to optimisations and the fact that the FPU does calculations at a higher precision than floats or doubles. (80 bits)   ;  Even if you were using the same floating point mode in release and debug, you would still have problems because the optimizer (which is on in release but not in debug) could re-order the operations of your math, which could result in different numbers.so many things can foil your plans in trying to make a deterministic game...but it is possible!In this case, you would just have to live with there possibly being differences in playback in debug and release.Edit: oops sorry wrong thread :/   ;Quote:Even if you were using the same floating point mode in release and debug, you would still have problems because the optimizer (which is on in release but not in debug) could re-order the operations of your math, which could result in different numbers.It only reorders operations if you use FP:Fast. FP Optimisations which change the output are disabled in Precise/Strict mode for this very reason.   