[英]How can I confirm the range of unsigned long integer in C?
unsigned long在我的Linux gcc上有8個字節。
unsigned long long在我的Linux gcc上也有8個字節。
所以我認為它們可以顯示的整數范圍是從0分鍾到最大(2 ^ 64-1) 。
現在我想確認一下我是否正確。
這是我的代碼 :
#include <stdio.h>
int main(void)
{
printf("long takes up %d bytes:\n", sizeof(long));
printf("long long takes up %d bytes:\n", sizeof(long long));
unsigned long a = 18446744073709551615;
a++;
printf("a + 1 = %lu\n", a);
unsigned long long b = 18446744073709551615;
b++;
printf("b + 1 = %llu\n", b);
return 0;
}
但是,代碼無法編譯,我收到以下警告:
warning: integer constant is so large that it is unsigned
我哪里做錯了? 我該如何修改代碼?
當初始化NUM,您可以附加“UL”為unsigned long
和ULL為unsigned long long
。
例如:
unsigned long a = 18446744073709551615UL;
unsigned long long b = 18446744073709551615ULL;
此外,使用%zu
而不是%d
因為sizeof返回size_t
。
根據cppreference :
- 整數后綴(如果提供)可能包含以下一項或兩項(如果提供了兩者,則它們可以按任何順序出現:
unsigned-suffix
(字符u
或字符U
)long-suffix
(字符l
或字符L
)或long-long-suffix
(字符序列ll
或字符序列LL
)(自C99起)
C標准5.2.4.2.1整數類型的大小<limits.h>
:
1下面給出的值應替換為適用於#if預處理指令的常量表達式。 此外,除了
CHAR_BIT
和MB_LEN_MAX
,以下內容應替換為與根據整數提升轉換的對應類型的對象的表達式具有相同類型的表達式。 它們的實現定義值的大小(絕對值)應等於或大於顯示的值,並帶有相同的符號。
用-1初始化無符號數。 這將自動為C中的MAX值。
#include <stdio.h>
int main(void)
{
printf("long takes up %d bytes:\n", sizeof(long));
printf("long long takes up %d bytes:\n", sizeof(long long));
unsigned long a = -1;
printf("a = %lu\n", a);
unsigned long long b = -1;
printf("b = %llu\n", b);
return 0;
}
更新 :根據評論更改代碼:)
您可以在<limits.h>
找到一些有用的定義。
如何確認C中無符號長整數的范圍?
最好 ,只需使用<limits.h>
的宏。 它更好地自我記錄代碼的意圖。
unsigned long long b_max = ULLONG_MAX;
或者,將-1指定給無符號類型。 由於-1不在無符號類型的范圍內,它將通過添加該類型的MAX值加1來轉換為目標類型。即使在具有填充的稀有機器上也能工作。
...如果新類型是無符號的,則通過重復加或減一個可以在新類型中表示的最大值來轉換該值,直到該值在新類型的范圍內。 C11dr§6.3.1.32
對於無符號類型,最小值當然為0。
unsigned long long b_min = 0;
unsigned long long b_max = -1;
printf("unsigned long long range [%llu %llu]\n", b_min, b_max);
請注意,挑剔的編譯器會抱怨使用b_max = -1;
分配超出范圍的值b_max = -1;
。 使用ULLONG_MAX
。
我哪里做錯了?
警告“警告:整數常量太大而無符號”是由於18446744073709551615
是平台上long long
范圍之外的整數十進制常量。 簡單的十進制常量僅限於此。 附加U
或u
。 然后編譯器會考慮unsigned long long
。
unsigned long long b = 18446744073709551615u;
此外,沒有C規范說18446744073709551615是unsigned long long
的最大值。 至少必須如此。 它可能更大。 因此,指定b = 18446744073709551615u
可能不會分配最大值 。
我該如何修改代碼?
如上所示
正如rsp所述,您可以使用UL
和ULL
指定文字的類型。 但這不會導致您的算法代碼產生確鑿的結果。
您的打印值始終為0
因為
2^64 % 64 = 0 // 64 = 8 byte
2^64 % 32 = 0 // 32 = 4 byte
2^64 % 16 = 0 // 16 = 2 byte
正如你所看到的,變量大小總是加倍,所以如果我們使用8個字節的包裝數,它只會在較小的大小上包含多個類型並產生相同的結果。
sizeof
將顯示正確的值。
但通常你想在代碼中檢查這些東西,而不是在輸出上檢查,所以你可以按照Arndt Jonasson的建議使用limits.h
。
或者您可以在編譯時使用static_assert
進行檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.