#include cmpFsFd( float s, double d ) { float tmp = (float)d; return s == tmp ? 1 : 0; } int main(void) { double nv = 2.0 / 3; float foo = 2.0 / 3; if( foo == nv ) printf("True "); else printf("False "); if( cmpFsFd( foo, nv )) printf("True\n"); else printf("False\n"); return 0; } #### [19:48:23.40} C:\test>cl float.c /Fefloatv8.exe Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. float.c Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:floatv8.exe float.obj [19:49:59.60} C:\test>floatv8 False True ---------------------------------------------------- c:\test>cl float.c /Fefloatv6.exe Microsoft (R) 32-bit C/C++ Standard Compiler Version 13.00.9466 for 80x86 Copyright (C) Microsoft Corporation 1984-2001. All rights reserved. float.c Microsoft (R) Incremental Linker Version 7.00.9466 Copyright (C) Microsoft Corporation. All rights reserved. /out:floatv6.exe float.obj c:\test>floatv6 False True #### ; 15 : if( foo == (float)nv ) printf("True\n"); fld QWORD PTR _nv$[ebp] ## Load nv onto FPU stack fstp DWORD PTR tv79[ebp] ## store (and pop) it into a 32-bit (float) temporary fld DWORD PTR tv79[ebp] ## load it back onto the FPU stack fld DWORD PTR _foo$[ebp] ## load foo onto the FPU stack fucompp ## do the comparison fnstsw ax ## get the FPU status word into AX test ah, 68 ## 00000044H (Check for equality?) jp SHORT $LN2@main ## Jump push OFFSET $SG2485 ## or not ... call _printf #### ; 15 : if( foo == (float)nv ) printf("True\n"); fld QWORD PTR _nv$[ebp] ## Load nv to FPU stack fst DWORD PTR tv78[ebp] ## Store it to a temporary but... *** NEVER LOADS IT BACK *** *** And does the comparison between the FPU register and the memory image of foo *** fcomp DWORD PTR _foo$[ebp] fnstsw ax test ah, 68 ; 00000044H jp SHORT $L800 push OFFSET FLAT:$SG801 call _printf