[英]C++ Arithmetic With Mixed Integral Types That Causes Overflow
我已經在VC ++ 2010中進行了一些測試,這些測試混合了大小不同的操作數,這些操作數會導致添加操作溢出:
int _tmain(int argc, _TCHAR* argv[])
{
__int8 a=127;
__int8 b=1;
__int16 c=b+a;
__int8 d=b+a;
printf("c=%d,d=%d\n",c,d);
return 0;
}
//result is: c=128, d=-128
我不明白為什么c == 128! 我的理解是,在這兩個加法中,b + a仍被視為2個帶符號的8位變量的加法。 因此結果是溢出,即-128。 之后,然后將結果提升為16位帶符號的int以進行第一次賦值操作,並且c仍應獲得16位-128的值。 我的理解正確嗎? c ++標准有點難以閱讀。 第4章似乎在談論整數提升,但是我找不到與此特定示例相關的任何內容。
我的理解是,在這兩個加法中,b + a仍被視為2個帶符號的8位變量的加法。 因此結果是溢出,即-128。
不可以,促銷活動會在評估+
之前發生,而不是在評估之后。 當a
和b
均為正數時發生加法。 兩個數字都被提升為int
,以進行加法,將其作為兩個正數相加,然后轉換為16位short。 該過程在任何時候都不會由於溢出而變為負數,因此最終結果為128。
可以說,這是有道理的: a
和b
的行為與數學中兩個數字的行為相匹配,這使語言從業者更加直觀。
1如果整數轉換等級(4.13)小於int等級的bool,char16_t,char32_t或wchar_t以外的整數類型的prvalue如果int可以表示源的所有值,則可以將其轉換為int類型的prvalue類型; 否則,可以將源prvalue轉換為unsigned int類型的prvalue。 [§4.5]
在此聲明中
__int16 c=b+a;
首先,所有
char
和short int
值都將自動提升為int
。 這個過程稱為整體提升 。 接下來,將所有操作數轉換為最大操作數的類型,這稱為類型提升 。 [赫伯特·希爾德]
變量b
和a
的值將提升為int
,然后對其進行運算。
在二進制補碼整數表示中,有符號值通過設置最高位來表示。 這樣,無論整數是否帶符號,機器都可以使用相同的指令加減二進制整數。
a = 127 == 0x7F == 0b01111111
+ b = 1 == 0x01 == 0b00000001
-------------------------------
c = 128 == 0x80 == 0b10000000
d =-128 == 0x80 == 0b10000000
變量c
和d
可以具有不同的類型,但是不同類型的整數僅僅是單個二進制值的不同解釋。 正如您在上面看到的,二進制值恰好適合8位。 由於標准要求在完成任何數學運算之前 ,將數學表達式的術語進行零或符號擴展(提升)到機器字的大小,並且兩個操作數都不會被符號擴展,因此無論哪種類型,結果始終為0b10000000
操作數是。
總而言之,結果之間的區別在於,對於16位整數,符號位是0b1000000000000000
( a+b
沒有),對於8位整數,符號位是0b10000000
( a+b
實際上具有) )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.