直接上代碼
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; // 輸出什嗎?
請問輸出結果如何?
11065353216false00true
為什麼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 = a0093164E call @ILT+340(__ftol2_sse) (931159h) //具體做什麼不太清楚好像望城了從float到long類型的轉換,得到的值為100931653 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)肯定輸出false009316BB 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