標籤:

C++ 整型提升的相關問題?

可能有點咬文嚼字了。可是我還是百思不得其解

這個是C++ Primer 5th 中文版 第143頁的一段話。

話中提到了整型提升。本來很好理解。畢竟int是符合cpu位數的,運算速度更快。

但是看到途中cval+fval。注釋中首先寫的是先進行整型提升為int,再將int值轉換為float。。

但是有段話:

如果任一操作數是 long double 類型,則將另一個操作數轉換為 long double 類型。

如果未滿足上述條件,並且任一操作數是 double 類型,則將另一個操作數轉換為 double 類型。

如果未滿足上述兩個條件,並且任一操作數是 float 類型,則將另一個操作數轉換為 float 類型。

如果未滿足上述三個條件(所有操作數都不是浮點型),則對操作數執行整型轉換,如下所示:

如果任一操作數是 unsigned long 類型,則將另一個操作數轉換為 unsigned long 類型。

如果未滿足上述條件,並且任一操作數是 long 類型且另一個操作數是 unsigned int 類型,則將兩個操作數都轉換為 unsigned long類型。

如果未滿足上述兩個條件,並且任一操作數是 long類型,則將另一個操作數轉換為 long 類型。

如果未滿足上述三個條件,並且任一操作數是 unsigned int類型,則將另一個操作數轉換為 unsigned int 類型。

如果未滿足上述任何條件,則將兩個操作數轉換為 int 類型。

換句話說就是:如果某個操作數的類型在上面這個列表中排名較低,那麼它首先將轉換成另外一個操作數的類型然後執行。

如果這樣來說,為什麼

這不是互相違背了么。

後來樓主做了一個實驗

```

char a=1;

float b=1;

float=a+b;

```

再vs編譯器下查看代碼,發現彙編代碼確實是吧char進行movsx

上面那段規則是msdn上的資料。

那麼,到底char和float進行算術運算,char會不會被整形提升呢?

有人說因為float是32位,int 也是32位,char轉float只能這樣轉換。

那char 和double算術運算,char會轉換為64位long?

這樣說的話,是不是上面圖片的提升,不應該理解為整型提升


你的概念有錯誤

整形提升,integral promotion,是針對表達式中單個操作數進行的,簡單說就是不到int的操作數都先提升到int或者unsigned int。

而你說的那個char+float的char變成float,執行的叫做usual arithmetic conversion,不是整形提升,是當二元運算符兩個操作數經過integral promotion之後,類型仍不相同的時候,較小的類型會被提升到較大的類型進行計算。

我寫過一篇文章,你可以去看看,整理一發C++整數運算的所有細節


對於一個char,它轉int16_t、int32_t、int64_t本來就只是幾個不同的指令而已,而這些數字轉float和double也還是那麼幾個指令。所以char到float/double到底是先通過哪個類型的整數類型其實並不重要,因為char的範圍就擺在那裡,float/double的精度和範圍也擺在那裡,是100%精確轉換的,用哪個整數類型做中介都不會有變化。


因為char到int幾乎是無開銷的,你看到的movsx就相當於把char轉換成了int(eax是32位)。

char和double運算一般不會被轉換為long。

因為並不是只有64位和64位類型進行轉換,而是如果針對char/short/int都設計一套轉換到float/double的操作,就太浪費了。

既然char/short到int都幾乎沒開銷,現代寄存器又至少是32位的,那就設計一個32位數據到float/double的轉換就行了,小於32位的則先提升到32位(反正整型提升不會溢出,原數據16位甚至更少,轉成float也不丟精度)


推薦閱讀:

如何用 C/C++ 求 1 到 1000 內的所有完全數?
用很厚的教材學編程的時候,該如何一邊攤開書一邊敲代碼?
怎麼理解 `auto var = [&]() { /* things to do */ }`?
C++的std::thread是怎麼進行參數傳遞的?
如何評價 C++14 ?

TAG:C | CPrimer |