2017-09-01 70 views
0

我有一些要存儲在signed 32 bit integer上的signed 8 bit值。使用按位將int值存儲在int上,並在沒有強制轉換的情況下保存值符號值時正確無誤

我這樣做,移動使用逐移值左:

const auto value1 = char{90}; 
const auto value2 = char{80}; 
const auto value3 = char{70}; 
const auto value4 = char{60}; 

auto merged_value = int32_t{0}; 
merged_value |= (value1 & 0x000000FF) << 24; 
merged_value |= (value1 & 0x000000FF) << 16; 
merged_value |= (value1 & 0x000000FF) << 8; 
merged_value |= value1 & 0x000000FF; 

現在,讓我們說,我想回去value1merged_value我是這樣做的:

const auto back_value1 = (merged_value >> 24) & 0x000000FF; 

該作品偉大的只要value1是一個正數,但如果該值是負數,返回值將是錯誤的。

例如,如果value1-80,然後back_value1176,這是因爲最顯著位(正或負位)是在比特位置7,而不是在31(因爲back_value1int32_t)。

現在,我知道我只需要對char進行演員製作back_value1,我將獲得-80值。但是我想要的是一個按位操作,它會給我正確的值-80back_value1back_value1int32_t而沒有投到char

感謝

編輯:

尼爾·巴特沃思問,我在這裏,而不是在一個在線IDE張貼整個代碼,所以這裏是:

#include <iostream> 
#include <bitset> 

int main() 
{ 
    const auto value = char{-80}; 
    std::cout << "value: " << (int)value << std::endl; 

    std::cout << "value bits: " << std::bitset<32>(value) << std::endl; 

    auto merged_value = uint32_t{0}; 
    merged_value |= (value & 0x000000FF) << 24; 

    const auto back_value = int32_t(merged_value >> 24) & 0xFF; 

    std::cout << "value: " << back_value << std::endl; 
    std::cout << "back_value bits: " << std::bitset<32>(back_value) << std::endl; 
} 
+1

「我想存儲在一個有符號的32位整數。」 - 爲什麼要簽名? –

+0

它不是,也可以是一個無符號的32位,因爲它最終只是一個容器,我只是把簽名變得更具體,但我想它只是造成了混淆。 –

+5

這看起來像另一個例子,使用正確的顯式類型而不是'auto'會解決問題,或者至少簡化它。 –

回答

0

答案是:爲了得到與原始int8_t相同符號的int32_t的值,您需要:

投回int8_t

const auto back_value1 = int32_t(int8_t((merged_value >> 24) & 0xFF)); 

,或者確保你所需要的字節在int32_t的左端前,右移:

const auto back_value1 = merged_value /* << 0 */ >> 24; 
const auto back_value2 = merged_value <<8>> 24; 

不用說了,我不推薦後者。

相關問題