程序不将变量识别为long int或unsigned int

时间:2015-08-13 21:52:33

标签: c integer overflow long-integer unsigned-integer

而不是获得数字" 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);
}

2 个答案:

答案 0 :(得分:4)

由于常量1int,当向左移动时,它仍为int。如果您想要unsigned long long,请将其设为:

unsigned long long mpy = 1ULL << multiplier++;

您可以使用其中一个后缀LULLL代替longunsigned longlong long代替{和}这些的案例版本,但后缀最好以大写字母书写,以避免混淆l1)。选择取决于你真正想要做的事情。

请注意<<的结果类型是左侧操作数的类型。移位的结果仅随后转换为赋值运算符的左侧类型。赋值的LHS不影响如何计算RHS的值。

正如user3528438comment指出的那样,正如我假设(可能是错误的)你会知道 - 如果multiplier<<运算符的RHS)评估如果为负值或等于或大于整数类型中位数的值,则调用未定义的行为。

请注意,long longunsigned long long是十五年旧标准(C99)和新版C11标准的标准配置 - 但它们不属于四分之一世纪的旧C89标准/ C90标准。如果你被困在一个平台上,在这个平台上,编译器处于201x年的时间扭曲发布日期和1990年的C标准兼容日期 - 那么你必须采用其他特定于平台的64位技术。更新后的问题中的循环包含33个值,因为从32开始计数到包括0,没有32位类型将为33个班次中的每一个都有不同的值。

(高级用户可能会对INT35-C Use correct integer precisionsN1899 — 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,intlong都是32位,如果要存储更大的数字,则需要升级到__int64。使用32位模式的gcc或其他编译器时,会遇到int = long = 32位的相同问题,这对您的情况没有帮助。只有当您在非Microsoft编译器上进行64位编译时,intlong才会出现分歧。

每个评论部分编辑: int64_tlong long也可以是符合标准的类型。或者,unsigned允许海报将其值调整为32位。