假設我的項目包括從包含該第三方庫頭:如何計算有符號位域的最大支持值?
struct foo {
signed int x:4;
};
沒有假設位字段總會有寬4,並且不依賴於實現定義的行爲,我怎麼能確定可存儲在會員x
中的最大值?
假設我的項目包括從包含該第三方庫頭:如何計算有符號位域的最大支持值?
struct foo {
signed int x:4;
};
沒有假設位字段總會有寬4,並且不依賴於實現定義的行爲,我怎麼能確定可存儲在會員x
中的最大值?
基本上你不能。問題與確定INT_MAX
或INT_MIN
相同:因爲你自己無法確定這些,所以編譯器實現必須爲提供這些值。 (你所能做的只是確定符號位的位置是否定義了實現(甚至是未定義的)行爲:溢出,移位運算符)
對於位域,實現不能提供這些值,所以你被卡住了。
這是bitfields真的不應該是signed
的原因之一。位字段用於位操作,沒有別的,符號位則被浪費了。
如果你的領域是unsigned
事情會很容易。你只需要在其中存儲-1
,你會得到所有的值,即「類型」的最大值。
,因爲它不能與sizeof
計算位字段的大小,這可以幫助:
#include <stdio.h>
struct foo {
signed int x: 4;
};
#define BIT(n) (1l << (n))
#define BIT_MASK(len) (BIT(len) - 1)
int main(void)
{
struct foo f = {0};
long i = 0;
while (f.x >= 0) {
f.x = BIT_MASK(++i);
}
printf("bits=%ld max=%ld\n", i, BIT_MASK(i));
return 0;
}
左移,直到f.x
爲負。
編輯:
上面的代碼是實現定義的,檢查這一項,我認爲這會工作(但你必須處理大端):
#include <stdio.h>
#include <string.h>
struct foo {
signed int x: 4;
};
#define BIT(n) (1l << (n))
#define BIT_MASK(len) (BIT(len) - 1)
int main(void)
{
long x, i = 0;
struct foo f;
f.x = -1;
memcpy(&x, &f, sizeof(f));
while (1) {
if (!(x & BIT(++i))) break;
}
printf("bits=%ld max=%ld\n", i, BIT_MASK(i));
return 0;
}
,你可以現在看它不超過2 ^(n-1)-1(作品在long
)
這是非常好的答案! David RF你應該添加一些評論和解釋。 –
OP(@Richard漢森):選中此代碼工作@ [鍵盤](http://codepad.org/aWKoshW3) –
謝謝Grijesh;) –
如果我這樣做,我會嘗試加載一個-1,如果它是2的補碼錶示,那麼它將是可以存儲的最大正值。 以上案例
foo.x = -1; unsigned int max_size =(unsigned int)(foo.x);
其中一半將是無符號最大值,一半+ 1將是最大符號值
可靠地,您只能存儲'1111'。 –
@GrijeshChauhan:「沒有假設位域將始終具有寬度4」。第三方開發者可能會在下一個版本中將寬度更改爲5。或者13.或者其他的東西。當位域的寬度發生變化時,我不希望我的代碼中斷。 –
我沒有得到:(,*'不假設位字段將始終具有寬度4 * *它將始終有4 - 與任何編譯器...我錯過了什麼嗎? –