編譯器如何處理型別轉換

2022-05-28 10:51:11 字數 2706 閱讀 4152

在兩種型別之間做轉換,轉換結果將取決於兩種型別的精度:

1. 精度是n的有符號整數型別應該用n個bit表示,取值範圍至少應該覆蓋(-2n-1, 2n-1)。例如signed char型用8個bit表示,表示的取值範圍是[-128, 127],也可以說是覆蓋了(-128, 128),所以這種型別的精度是8。

2. 精度是n的無符號整數型別應該用n個bit表示,取值範圍是[0, 2n-1]。

3. 精度是n的浮點數型別的取值範圍至少應該覆蓋(-2n-1, 2n-1)的整數值。

現在要把乙個精度是m的型別(值為x)轉換成乙個精度是n的型別,所有可能的情況如下表所示:

待轉換的型別

n < m的情況

n == m的情況

n > m的情況

signed integer to signed integer

discard m.s. m-n bits (can overflow)

same value

same value

unsigned integer to signed integer

if (x < 2n-1) same value else impl.-def.(can overflow)

if (x < 2n-1) same value else impl.-def.(can overflow)

same value

floating-point to signed integer

if (|x| < 2n-1) trunc(x) else imple.-def. (can overflow)

if (|x| < 2n-1) trunc(x) else imple.-def. (can overflow)

if (|x| < 2n-1) trunc(x) else imple.-def. (can overflow)

signed integer to unsigned integer

if (0 <= x) x % 2n else impl.-def.

if (0 <= x) same value else x + 2n

if (0 <= x) same value else x + 2n

unsigned integer to unsigned integer

x % 2n

same value

same value

floating-point to unsigned integer

if (0 <= x < 2n) trunc(x) else imple.-def. (can overflow)

if (0 <= x < 2n) trunc(x) else imple.-def. (can overflow)

if (0 <= x < 2n) trunc(x) else imple.-def. (can overflow)

signed integer to floating-point

keep sign, keep m.s.n-1 bits

same value

same value

unsigned integer to floating-point

+ sign, keep m.s. n-1 bits

+ sign, keep m.s. n-1 bits

same value

floating-point to floating point

keep m.s. n-1 bits (can overflow)

same value

same value

上表中的一些縮寫說明如下:

impl.-def.表示implementation-defined;

m.s. bit表示mostsignificant bit;

trunc(x)表示取x的整數部分,即truncate toward zero;

x % y就是取模

用法:float型轉short型,對應表中的floating-point to signed integer一行,可以看到,不管兩種型別的精度如何,處理方式是一樣的,如果float型別的值在(-32768.0, 32768.0)之間,則截掉小數部分就可以了,如果float型別的值超出了這個範圍,則轉換結果是未明確定義的,有可能會產生溢位,例如對於short s =32768.4。 

把int型別轉換成unsigned short型別,對應表中的unsigned integer to unsigned integer一行,如果int型別的值是正的,則把它除以216取模,其實就是取它的低16位,如果int型別的值是負的,則轉換結果是未明確定義的。

把int型別轉換成short型別,對應表中的第一行signed integer to signed integer,把int型別值的高16位丟掉(這裡的m.s.包括符號位在內,上表中另外幾處提到的m.s.應該是不算符號位在內),只留低16位,這種情況也有可能溢位,例如對於short s = -32769。

把short型轉換成int型,仍然對應表中第一行,轉換之後應該是same value。那怎麼維持值不變呢?是不是在高位補16個0就行了呢?如果short型的值是-1,按補碼表示就是十六進製制ffff,要轉成int型的-1需要變成ffffffff,因此需要在高位補16個1而不是16個0。換句話說,要維持值不變,在高位補1還是補0取決於原來的符號位,這稱為符號擴充套件(sign 

extension)。 

編譯器是如何處理new和delete的

complex pc newcomplex 1 2 complex為類名 複數 再編譯器處理這一語句的時候,先分配複數的記憶體,然後進行轉型,最後呼叫建構函式 void men operator new sizeof complex 第一步,分配記憶體 pc static cast men 第二步,...

C 編譯器如何對資料進行型別轉換

本人是c 行業的小白剛入行倆月多點,剛剛查資料學習了一些型別轉換原理,也就是編譯器編譯時如何對資料進行型別轉換。不知道對不對就沒做筆記但是還想記錄一下就發個帖子吧,歡迎各位大佬指教指教,有錯誤技術提出,小老弟不勝感激!進入正題。型別轉換大體上應該分隱是轉換 顯示轉換 方法轉換 自定義轉等換這幾類。編...

撥開字元編碼的迷霧 編譯器如何處理檔案編碼

使用visual studio建立的c 工程可以在工程屬性配置屬性 常規中配置字符集 使用unicode字符集 預設 使用多位元組字符集。這個設定項不對字元編碼產生直接的影響 注意這裡的 直接 二字,第3節會說到 只會在工程屬性配置屬性 c c 預處理器加入相應的巨集 使用unicode字符集 un...