直接上代码
float a = 1.0f;
cout << (int)a << endl;
cout << (int&)a << endl;
cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
float b = 0.0f;
cout << (int)b << endl;
cout << (int&)b << endl;
cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
请问输出结果如何?
1
1065353216
false
0
0
true
为什么0.0f和1.0f有这么大的差别呢?让我们反汇编看看代码如何?
00931620 push ebp
00931621 mov ebp,esp
00931623 sub esp,0D8h
00931629 push ebx
0093162A push esi
0093162B push edi
0093162C lea edi,[ebp-0D8h]
00931632 mov ecx,36h
00931637 mov eax,0CCCCCCCCh
0093163C rep stos dword ptr es:[edi]
float a = 1.0f;
0093163E fld1 //将1.0f装载到st(0)
00931640 fstp dword ptr [a]
cout << (int)a << endl;
00931643 mov esi,esp
00931645 mov eax,dword ptr [__imp_std::endl (93D31Ch)]
0093164A push eax
0093164B fld dword ptr [a] //st0 = a
0093164E call @ILT+340(__ftol2_sse) (931159h) //具体做什么不太清楚好像望城了从float到long类型的转换,得到的值为1
00931653 mov edi,esp
00931655 push eax
00931656 mov ecx,dword ptr [__imp_std::cout (93D318h)]
0093165C call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]
00931662 cmp edi,esp
00931664 call @ILT+505(__RTC_CheckEsp) (9311FEh)
00931669 mov ecx,eax
0093166B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]
00931671 cmp esi,esp
00931673 call @ILT+505(__RTC_CheckEsp) (9311FEh)
cout << (int&)a << endl;
00931678 mov esi,esp
0093167A mov eax,dword ptr [__imp_std::endl (93D31Ch)]
0093167F push eax
00931680 mov edi,esp
00931682 mov ecx,dword ptr [a] //输出a地址内容(强制将内容转换为int类型),a内存中的内容为3f800000(float的编码方式),强制转换为int类型得到了3f800000的10进制值
00931685 push ecx
00931686 mov ecx,dword ptr [__imp_std::cout (93D318h)]
0093168C call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]
00931692 cmp edi,esp
00931694 call @ILT+505(__RTC_CheckEsp) (9311FEh)
00931699 mov ecx,eax
0093169B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]
009316A1 cmp esi,esp
009316A3 call @ILT+505(__RTC_CheckEsp) (9311FEh)
cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
009316A8 mov esi,esp
009316AA mov eax,dword ptr [__imp_std::endl (93D31Ch)]
009316AF push eax
009316B0 fld dword ptr [a]
009316B3 call @ILT+340(__ftol2_sse) (931159h)
009316B8 cmp eax,dword ptr [a] //(1==0x3f800000)肯定输出false
009316BB sete cl
009316BE mov edi,esp
009316C0 movzx edx,cl
009316C3 push edx
009316C4 mov ebx,esp
009316C6 push offset std::boolalpha (931113h)
009316CB mov ecx,dword ptr [__imp_std::cout (93D318h)]
009316D1 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D30Ch)]
009316D7 cmp ebx,esp
009316D9 call @ILT+505(__RTC_CheckEsp) (9311FEh)
009316DE mov ecx,eax
009316E0 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D308h)]
009316E6 cmp edi,esp
009316E8 call @ILT+505(__RTC_CheckEsp) (9311FEh)
009316ED mov ecx,eax
009316EF call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]
009316F5 cmp esi,esp
009316F7 call @ILT+505(__RTC_CheckEsp) (9311FEh)
float b = 0.0f;
009316FC fldz
009316FE fstp dword ptr [b]
cout << (int)b << endl;
00931701 mov esi,esp
00931703 mov eax,dword ptr [__imp_std::endl (93D31Ch)]
00931708 push eax
00931709 fld dword ptr [b]
0093170C call @ILT+340(__ftol2_sse) (931159h)
00931711 mov edi,esp
00931713 push eax
00931714 mov ecx,dword ptr [__imp_std::cout (93D318h)]
0093171A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]
00931720 cmp edi,esp
00931722 call @ILT+505(__RTC_CheckEsp) (9311FEh)
00931727 mov ecx,eax
00931729 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]
0093172F cmp esi,esp
00931731 call @ILT+505(__RTC_CheckEsp) (9311FEh)
cout << (int&)b << endl;
00931736 mov esi,esp
00931738 mov eax,dword ptr [__imp_std::endl (93D31Ch)]
0093173D push eax
0093173E mov edi,esp
00931740 mov ecx,dword ptr [b]
00931743 push ecx
00931744 mov ecx,dword ptr [__imp_std::cout (93D318h)]
0093174A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D314h)]
00931750 cmp edi,esp
00931752 call @ILT+505(__RTC_CheckEsp) (9311FEh)
00931757 mov ecx,eax
00931759 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]
0093175F cmp esi,esp
00931761 call @ILT+505(__RTC_CheckEsp) (9311FEh)
cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
00931766 mov esi,esp
00931768 mov eax,dword ptr [__imp_std::endl (93D31Ch)]
0093176D push eax
0093176E fld dword ptr [b]
00931771 call @ILT+340(__ftol2_sse) (931159h)
00931776 cmp eax,dword ptr [b] //b对应内容为0x00000000,转换之后依然为0所以相等
00931779 sete cl
0093177C mov edi,esp
0093177E movzx edx,cl
00931781 push edx
00931782 mov ebx,esp
00931784 push offset std::boolalpha (931113h)
00931789 mov ecx,dword ptr [__imp_std::cout (93D318h)]
0093178F call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D30Ch)]
00931795 cmp ebx,esp
00931797 call @ILT+505(__RTC_CheckEsp) (9311FEh)
0093179C mov ecx,eax
0093179E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D308h)]
009317A4 cmp edi,esp
009317A6 call @ILT+505(__RTC_CheckEsp) (9311FEh)
009317AB mov ecx,eax
009317AD call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (93D310h)]
009317B3 cmp esi,esp
009317B5 call @ILT+505(__RTC_CheckEsp) (9311FEh)
如此就可以推导出结果对应为
1
0x3f800000
false
0
0
true