2017-02-21 76 views
0

我有一個size_t變量nOffset,其中包含我想知道實際需要多少字節來存儲它。我想MSB的位置也可以使用?這是到目前爲止我的代碼(sizeof(size_t) 4):如何找出需要多少字節來存儲一個值(int)在C

int nLen = 0; 
if (nOffset > 0xFFFFFF) 
{ 
    nLen = 4; 
} 
else if (nOffset > 0xFFFF) 
{ 
    nLen = 3; 
} 
else if (nOffset > 0xFF) 
{ 
    nLen = 2; 
} 
else 
{ 
    nLen = 1; 
} 
+0

另一種方法,不一定要好得多,就是用循環來檢查除底部(最低有效)字節以外的所有字節是否有非零位。 –

+1

最好使用信息論中的公式,而不是循環: '(size_t)(log(number)/ log(2))' – EgorBr

+0

實際上,OP的代碼(本質上是一個展開的循環)將比一個循環,這反過來會比計算對數更快。 –

回答

1

這是很容易使用循環和預定義的常量。

將整數除以字節的最大值可以表示加1,直到得到零。迭代計數是字節。

以下輸出到存儲整數的精度所需的字節數:

size_t a = SIZE_MAX; 

size_t bytes = 0; 
while(a != 0) 
{ 
    a /= (1u << CHAR_BIT); 
    bytes++; 
} 
+0

由於這些值是無符號值,因此可以在一個循環中用簡單的a >> = CHAR_BIT;替換a/=(1u << CHAR_BIT);'。 – user694733

+0

@ user694733最初的代碼是處理有符號整數。 – 2501

1

可以在GCC

使用以下內置函數 - 內置功能:int __builtin_clz (unsigned int x)
返回X中前導0位的數量,從最高位位置開始。如果X0,結果是未定義的。

- 內置功能:int __builtin_clzl (unsigned long)
類似__builtin_clz,除了參數類型爲unsigned long

- 內置功能:int __builtin_clzll (unsigned long long)
類似__builtin_clz,除了參數類型爲unsigned long long

找到的前導零的數目後,它是簡單的計算(num_bits =在int比特數 - 前導零)找到所需要的比特的數目。您可以更改爲(num_bits + 7)/8所需的字節數。

+1

[示例代碼](http://ideone.com/H1f1o7)。你可以添加'if(u == 0)return 1;'如果0輸入是可能的。 –

+0

'_BitScanReverse'可以在MSVC上用於類似的目的 – sp2danny

+0

OP沒有提到GCC,所以我假設他們想要標準C中的解決方案。 – Lundin

1

如果您正在尋找多少字節採取的int變量,你可以看看到limits.h庫,特別是INT_MININT_MAX常量,那麼可以計算的字節數。

如果你正在尋找需要多少字節編碼一定的整數,在

  1. 使用的算法,找到2 pow(2, N)這等於或大於整數長度最小功率,N是最少的位數。這很簡單,但是當整數爲負數時有一個小錯誤,請參閱https://softwareengineering.stackexchange.com/questions/239036/how-are-negative-signed-values-stored

  2. 或嘗試打印出數字的位數並對它們進行計數,請參閱C printing bits

0

簡單地遍歷從MSB開始的數據,並用0xFF掩碼每個字節。要知道哪個字節是MSB可移植的,你必須使用位移。

在這段代碼中,i是要移位的位數。

size_t i; 
for(i=sizeof(data)*8; i!=0; i-=8) 
{ 
    if((data >> (i-8)) & 0xFF) 
    { 
    break; 
    } 
} 

size_t bytes_to_copy = i/8; 
相關問題