回复 20楼 cosdos
嗯,也有这种可能

重剑无锋,大巧不工
程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 17.00.61030.0
TITLE D:\Projects\test\Project9\Project9\main.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
PUBLIC _main
PUBLIC ??_C@_05LCCCBGPN@True?6?$AA@ ; `string'
EXTRN __imp__printf_s:PROC
EXTRN __imp___getch:PROC
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_InitBase:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __fltused:DWORD
; COMDAT rtc$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ ENDS
; COMDAT ??_C@_05LCCCBGPN@True?6?$AA@
CONST SEGMENT
??_C@_05LCCCBGPN@True?6?$AA@ DB 'True', 0aH, 00H ; `string'
CONST ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File d:\projects\test\project9\project9\main.cpp
; COMDAT _main
_TEXT SEGMENT
_n$ = -8 ; size = 4
_main PROC ; COMDAT
; 5 : {
push ebp
mov ebp, esp
sub esp, 204 ; 000000ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-204]
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd
; 6 : int n = 0x80000000;
mov DWORD PTR _n$[ebp], -2147483648 ; 80000000H
; 7 :
; 8 : if (n == (int)(float) n)
cvtsi2ss xmm0, DWORD PTR _n$[ebp]
cvttss2si eax, xmm0
cmp DWORD PTR _n$[ebp], eax
jne SHORT $LN1@main
; 9 : {
; 10 : printf_s("True\n");
mov esi, esp
push OFFSET ??_C@_05LCCCBGPN@True?6?$AA@
call DWORD PTR __imp__printf_s
add esp, 4
cmp esi, esp
call __RTC_CheckEsp
$LN1@main:
; 11 : }
; 12 : _getch();
mov esi, esp
call DWORD PTR __imp___getch
cmp esi, esp
call __RTC_CheckEsp
; 13 : }
xor eax, eax
pop edi
pop esi
pop ebx
add esp, 204 ; 000000ccH
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

程序代码:#include <stdio.h>
//精度损失
void demo1( )
{
int n = 0;
float f = n ;
// float f = n ;汇编代码
// fild DWORD PTR _n$[ebp] ;把n的值放到浮点寄存器( 80位 ), 远大于 32bits,精度无损
// fstp DWORD PTR _f$[ebp] ;这里把浮点寄存器( 80位 )的值返回到变量f( 32位 ),造成精度损失
// 原因:float变量内存结构:1bit(符号位) 8bits(指数位) 23bits(尾数位)
// 当 n有效位 > 24bits 时,尾数丢失
if (n==(int)f) //上面 n = 0; n< 24bits, 因此精度无损,输出TRUE
printf("TRUE\n");
else
printf("Flase\n");
n = 0x1ffffff ;//这里 n为25bits , 且超出24bits部分不为0
f = n ;
if (n==(int)f) //这里 n为25bits , n> 24bits, 因此精度丢失,输出Flase
printf("TRUE\n");
else
printf("Flase\n");
n = 0x1fffff0 ;//这里 n为25bits , 且最后4bit为0 , 丢失后与丢失前相同(都是零)
f = n ;
if (n==(int)f) // 因此精度丢失,但丢失前后相同,输出TRUE
printf("TRUE\n");
else
printf("Flase\n");
}
//精度无损
void demo2( )
{
int n;
if (n==(int)(float)n)
//反汇编代码
//fild DWORD PTR _n$[ebp] ;把n的值放到浮点寄存器( 80位 ), 远大于 32bits,精度无损
// call __ftol ;把浮点寄存器的值放到eax , 精度无损,原因:eax就是无符号整型
// cmp DWORD PTR _n$[ebp], eax ;将n的值与eax比较,恒相等。
printf("TRUE"); //输出True
else
printf("Flase");
}
int main( )
{
demo1( );
demo2( );
return 0;
}测试结果:TRUE FALSE TRUE TRUE
程序代码:#include <stdio.h>
int main( )
{
//恒输出TRUE
int n;
if (n==(int)(float)n)
printf("TRUE\n");
else
printf("False\n");
//三种情况
//1. n<0x1000001 时 , 转化为浮点数时没有丢失精度,程序输出TRUE
n = 5 ;
float f = n ;
if (n==(int)f)
printf("TRUE\n");
else
printf("False\n");
// 2. n>=0x1000001 时 ,可以分两种情况
// 2.1 从左往右数24位,大于24位的将被抛弃。
// 如果被抛弃的都是0 ,则抛弃前后没有影响,因为还原后还是0 , 程序输出TRUE
n = 0x1000010 ;
f = n ;
if (n==(int)f)
printf("TRUE\n");
else
printf("False\n");
// 2.2 如果被抛弃的数据中含有1 ,则因为还原后都是0 ,
// 所以造成n的低位与(int)f的低位不相等,程序输出False。
n = 0x1000001 ;
f = n ;
if (n==(int)f)
printf("TRUE\n");
else
printf("False\n");
return 0;
}