而不是获得数字" 2147483648"我得到" -2147483648"因为有符号的int溢出。我尝试将变量声明为long int和unsigned int,没有用。它们不被认为是这种类型。如果有人想知道的话,我就会贬低价值。
int multiplier = 1,i;
long int mpy = 0;
for(i=32;i>=0;i--){
mpy = 1 << multiplier++;
printf("mpy = %d\n",mpy);
}
答案 0 :(得分:4)
由于常量1
是int
,当向左移动时,它仍为int
。如果您想要unsigned long long
,请将其设为:
unsigned long long mpy = 1ULL << multiplier++;
您可以使用其中一个后缀L
或UL
或LL
代替long
,unsigned long
和long long
代替{和}这些的案例版本,但后缀最好以大写字母书写,以避免混淆l
和1
)。选择取决于你真正想要做的事情。
请注意<<
的结果类型是左侧操作数的类型。移位的结果仅随后转换为赋值运算符的左侧类型。赋值的LHS不影响如何计算RHS的值。
正如user3528438中comment指出的那样,正如我假设(可能是错误的)你会知道 - 如果multiplier
(<<
运算符的RHS)评估如果为负值或等于或大于整数类型中位数的值,则调用未定义的行为。
请注意,long long
和unsigned long long
是十五年旧标准(C99)和新版C11标准的标准配置 - 但它们不属于四分之一世纪的旧C89标准/ C90标准。如果你被困在一个平台上,在这个平台上,编译器处于201x年的时间扭曲发布日期和1990年的C标准兼容日期 - 那么你必须采用其他特定于平台的64位技术。更新后的问题中的循环包含33个值,因为从32开始计数到包括0,没有32位类型将为33个班次中的每一个都有不同的值。
(高级用户可能会对INT35-C Use correct integer precisions和N1899 — Integer precision bits update感兴趣;对于大多数人来说,他们有点深奥。我不确定我是否曾经发现有必要担心提出的问题。)
另请注意以下评论中有关printf()
格式的讨论。您应确保使用正确的格式打印值。对于long int
,应为%ld
;对于unsigned long long
,这将是%llu
。其他类型需要其他格式。确保您使用合理的编译器警告选项。如果您正在使用GCC,则应将gcc -Wall -Wextra -Werror -std=c11
视为一组相当有效的选项;我使用的选项比我编译C代码的选项稍微严格一些。
答案 1 :(得分:0)
根据您使用的编译器,以及您是否在32位与64位模式下进行编译,您所看到的内容可能完全符合预期。
https://software.intel.com/en-us/articles/size-of-long-integer-type-on-different-architecture-and-os
tl; dr:对于MSVC,int
和long
都是32位,如果要存储更大的数字,则需要升级到__int64
。使用32位模式的gcc或其他编译器时,会遇到int
= long
= 32位的相同问题,这对您的情况没有帮助。只有当您在非Microsoft编译器上进行64位编译时,int
和long
才会出现分歧。
每个评论部分编辑:
int64_t
或long long
也可以是符合标准的类型。或者,unsigned
允许海报将其值调整为32位。