2015-12-26 32 views

回答

2

在實踐中:你可以簡單地分配簽署價值爲uint8_t

u = i; 

,或者你可以用符號值初始化,

uint8_t u = i; 

這是假定簽訂了整數表示,這是今天普遍使用的。通過這種表示,位被完全保留。 「在實踐中」資格是指這個假設。


例如,在現代機器上,例如在一個現代機器上的8位有符號表示。 -42,是位模式編號-42 + 256,它是(位模式編號)214.將它轉換爲無符號是由標準保證產生相同的值模256.所以它是相同的位模式,即位模式214.


從標誌到無符號由標準明確定義,儘管位模式的保存通常只是一種實踐效果(所有現代計算機都是這樣設計的)。但是,如果無法表示無符號值,則會遇到編譯器特定的效果。這種轉換需要更加小心,因爲這是編譯器自行決定的問題,而不是硬件級別的實際保證。


(1)由於M.M.在his answer中說明了你的例子中的特定簽名類型,int8_t,是C11已經保證了C的二進制補碼。我在C99標準的最終草案中沒有看到這種語言,所以推測它不在C99中,因此不在基於C99的C++ 11或C++ 14中,但可​​能存在於C++ 17中,我相信它基於C11。

+0

無符號整數換行由標準定義,與整數表示無關。 (有簽名的包裝不是) –

+0

@JonPurdy:你看起來在你的視圖中缺少的位是標準允許樹不同的簽名表示,其中只有一個保證當值被轉換爲相應的無符號類型時保留位模式。 –

+0

啊,你是對的,我在閱讀你的答案時失去了問題的背景。這就是我打開太多選項卡所得到的結果。值得注意的是,僅僅從一個有符號值初始化一個無符號值並不會做出任何特定於平臺的假設。 –

0

隨着intN_t類型,你可以簡單地寫:

int8_t i = something; 
uint8_t u = i; 

,因爲這些類型都需要使用2的補碼錶示,此轉換被定義爲保留位。

參考:C++ 14 [cstdint.syn]/2:

頭定義所有的功能,類型和宏一樣7.18 C標準

和C11 7.20.1.1/1(C99 7.18.1.1):

typedef名intN_t表示一個符號整型與寬度N,沒有填充比特,和一個二的補碼錶示法。


爲了保護其他整數類型的代表性,使用:

int i = something; 
unsigned int i = *(unsigned int *)&i; 

你可以用任何一對相應的有符號和無符號類型做到這一點。除了生成陷阱表示的可能性之外,它是安全的。

+0

請提供「使用補碼錶示法所需的類型」的來源。 –

+0

@ Cheersandhth.-Alf添加了 –

+0

謝謝,我沒有在C99中看到它,並且不知道它已被添加。 –

0

嘗試顯式類型轉換。使用static_cast進行(不安全)類型轉換對於到達變量的「原始字節」是必需的。 要的值轉換爲給定類型,你寫了以下內容:

static_cast<type_to_convert_to>(expression) 

隨着投的static_cast在編譯時靜態檢查。

#include <iostream> 


int main() { 

    int8_t i {11}; 
    uint8_t i2 = static_cast<uint8_t>(i); 
    std::cout << "i occupies " << sizeof(i) << " bytes." << std::endl; 
    std::cout << "i2 occupies " << sizeof(i2) << " bytes." << std::endl; 


} 
相關問題