我正在编译下面的代码,由于某种原因,我不能将-2147483648分配给8字节长且已签名的变量。
long long x = -2147483648;
当我跨过这一行时,x的值是2147483648,MS Visual Studio中的'Watch'窗口显示x的类型是__int64。 sizeof(x)也返回8.
根据limit.h,签名长多的限制是:
#define LLONG_MAX 9223372036854775807i64 /* maximum signed long long int value */
#define LLONG_MIN (-9223372036854775807i64 - 1) /* minimum signed long long int value */
和
/* minimum signed 64 bit value */
#define _I64_MIN (-9223372036854775807i64 - 1)
/* maximum signed 64 bit value */
#define _I64_MAX 9223372036854775807i64
我只是不明白!!!
有人可以对此有所了解吗?
答案 0 :(得分:4)
如果没有LL,编译器似乎推断2147483648
是32位unsigned long
。 然后它应用-
运算符。结果是0 - 2147483648
。由于此值小于0且为unsigned long t
,因此会添加4294967296
,再次为2147483648
。然后将此值分配给long long x
。
推荐:
long long x = -2147483648LL;
// or
long long x = -2147483647 - 1;
答案 1 :(得分:2)
尝试分配到-2147483648LL
请参阅整数常量here
答案 2 :(得分:2)
您的代码在我的GCC 4.6.3编译器上编译并执行正常,其中--std = c99。我怀疑你正在使用微软提供的相当无望的所谓C编译器。它显然不是很聪明。使用较长的长后缀(i64
,ll
或LL
)来欺骗它的行为。
有趣的是,MS C ++编译器也无法做到这一点:
#include <iostream>
int main()
{
long long x = -2147483647;
std::cout << x << std::endl;
x = -2147483648;
std::cout << x << std::endl;
x = -2147483649;
std::cout << x << std::endl;
return 0;
}
<强>输出强>
-2147483647 2147483648 2147483647
我用VS2013的x86 C ++编译器编译了这个。
我从g ++ 4.6.3获得相同的输出。
所以我认为除此之外还有更多的东西。我希望比我更了解的人可以解释这一切。
答案 3 :(得分:1)
回答其他一些评论(对不起,因为我还没有足够的代表,所以无法回复每一条评论):
在C和C ++中,表达式的类型不依赖于其上下文。在这种情况下,-214743648
的类型由语言规则定义,以后您将其分配给long long
的事实不会影响这一点。
实际上这种做事方式使得语言比替代方案简单得多,这是首先吸引我使用C语言的一种方式。
在David Heffernan的例子中,
x = -2147483648;
std::cout << x << std::endl; // gives 2147483648
x = -2147483649;
std::cout << x << std::endl; // gives 2147483647
重要的是-
符号不是整数文字的一部分。表达式2147483648
是一个整数常量,其类型根据标准中的一组规则确定;然后将一元减号运算符应用于该值(不改变其类型)。
不幸的是,C90,C99,C ++ 98和C ++ 11对整数文字的类型都有不同的规则。此外,十进制常量的规则与十六进制或八进制常量的规则不同!您可以在相关的标准文档中查找它们。
如果您有32位整数,那么2147483648
太大而不能成为int
。在所有方言中,下一个可能的类型是long int
。如果您还有32位long ints
,则在C99或C ++ 11中它具有类型long long int
。在C90或C ++ 98中,它具有类型unsigned long int
。 (这些语言没有long long
类型)。
回到David Heffernan的例子。 C ++ 98没有long long
,因此要么使用C ++ 11编译器,要么使用Microsoft扩展。假设后者;谁知道他们决定对整数常量做什么,但如果他们保留了2147483648
类型为unsigned long int
的C ++ 98定义,那就可以解释结果。
答案 4 :(得分:0)
原来我只需要这样写:
long long x = -2147483648i64;
为什么编译器无法解决问题。我已经拼出了这个类型,为什么我必须把'i64'放在数字???
之后