while ((1U << i) < nSize) {
i++;
}
使用1U
代替1
的任何特定原因?
答案 0 :(得分:17)
在大多数编制者中,两者都会给出具有相同表示的结果。但是,根据C规范,对带符号参数的位移操作的结果给出了实现定义的结果,因此在理论中 1U << i
比1 << i
更便携。实际上,你遇到过的所有C编译器都会将左移位与无符号左移相同。
另一个原因是,如果nSize
未签名,则将其与签名的1 << i
进行比较将生成编译器警告。将1
更改为1U
会删除警告消息,如果i
为31或63,则无需担心会发生什么。
编译器警告很可能是1U
出现在代码中的原因。我建议在打开大多数警告的情况下编译C,并通过更改代码来消除警告消息。
答案 1 :(得分:5)
1U未签名。它可以携带两倍大的值,但没有负值。
根据环境的不同,使用U时,i最大可以是31或15,不会导致溢出。不使用U,我最多可以是30或14。
31,30是32位int 15,14是16位int
答案 2 :(得分:4)
如果nSize是int
,则最大值为2147483647(2 ^ 31-1)。如果您使用1
代替1U
,那么1 << 30
将获得1073741824而1 << 31
将为-2147483648,因此如果nSize大于1073741824,则while循环将永远不会结束
使用1U << i
,1U << 31
将评估为2147483648,因此您可以安全地将其用于nSize,最高可达2147483647.如果nSize是无符号整数,则循环也可能永远不会结束,在这种情况下,nSize可能大于1U << 31
。
修改:所以我不同意答案,告诉你nSize应该是无符号的,但如果签名那么它不应该是否定的......
答案 3 :(得分:1)
1U未签名。
他们在表达式中使用无符号值的原因是(我猜)因为nSize
也是无符号的,编译器(当用某些参数调用时)在比较有符号和无符号值时会发出警告。
另一个原因(不太可能,在我看来,但我们不知道不知道值nSize
应该假设)是无符号值可以是有符号值的两倍,所以nSize
最高可达〜4 * 10 ^ 9而不是〜2 * 10 ^ 9。