[英]2^32 - 1 not part of uint32_t?
這是編譯輸出讓我哭的程序:
#include <inttypes.h>
int main()
{
uint32_t limit = (1 << 32) - 1; // 2^32 - 1 right?
}
這是編譯輸出:
~/workspace/CCode$ gcc uint32.c
uint32.c: In function ‘main’:
uint32.c:5:29: warning: left shift count >= width of type [-Wshift-count-overflow]
uint32_t limit = (1 << 32) - 1; // 2^32 - 1 right?
我認為(1 << 32) - 1
等於 2^32 - 1 並且 32 位的無符號整數范圍從 0 到 2^32 - 1,是不是這樣? 我哪里做錯了?
警告是正確的,32 位數字中的最高位是第 31 位(0 索引),因此溢出前的最大移位是1 << 30
(30 因為符號位)。 即使您在某個時候執行-1
,也必須存儲1 << 32
的結果,並將其存儲在一個int
(在這種情況下恰好是 32 位)。 因此,您會收到警告。
如果您確實需要獲得32 bit unsigned int
的最大值,則應該以簡潔的方式進行:
#include <stdint.h>
uint32_t limit = UINT32_MAX;
或者更好的是,使用 c++ 限制頭文件:
#include <limits>
auto limit = std::numeric_limits<uint32_t>::max();
你有兩個錯誤:
1
是int
類型,因此您將初始值計算為int
,而不是uint32_t
。int
為 32 位或更少,則1 << 32
是未定義的行為。 (uint32_t)1 << 32
也將是未定義的。 (另外,請注意1 << 31
也是未定義的行為,如果int
是 32 位,因為溢出)
由於算術無論如何都是以2^32
為模完成的,因此一種更簡單的方法就是
uint32_t x = -1;
uint32_t y = (uint32_t)0 - 1; // this way avoids compiler warnings
嘗試計算目標常量時,編譯器在您的示例中內部使用 int 。 想象一下,rhe 編譯器沒有任何可用的優化,而是為您的班次生成匯編程序。 對於 32 位 int 移位指令,數字 32 會很大。
此外,如果您想設置所有位,請使用 ~0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.