3 回答
TA贡献1871条经验 获得超13个赞
-2147483648不是“数字”。C ++语言不支持负文字值。
-2147483648实际上是一个表达式:在其前面2147483648带有一元运算-符的正文字值。2147483648对于int您的平台范围的积极方面,价值显然太大。如果类型long int有你的平台上更大的范围,编译器将不得不自动假设2147483648有long int型。(在C ++ 11中,编译器还必须考虑long long int类型。)这将使编译器-2147483648在较大类型的域中求值,并且结果将为负数,这与预期的一样。
但是,显然在您的情况下,范围与的范围long int相同int,并且通常不存在比int平台更大的整数类型。正式地,这意味着正常数会2147483648溢出所有可用的带符号整数类型,这又意味着程序的行为是不确定的。(在这种情况下语言规范选择了未定义的行为,而不是要求诊断消息,这有点奇怪,但这就是事实。)
在实践中,考虑到行为是不确定的,2147483648可能会被解释为某些依赖于实现的负值,在-对它应用一元后,它会变成正值。或者,某些实现可能会决定尝试使用无符号类型来表示该值(例如,在C89 / 90中要求使用编译器unsigned long int,而在C99或C ++中则不需要)。允许执行任何操作,因为无论如何行为都是未定义的。
顺便说一句,这就是INT_MIN通常将like常量定义为的原因
#define INT_MIN (-2147483647 - 1)
而不是看似更直接
#define INT_MIN -2147483648
后者将无法按预期工作。
TA贡献1780条经验 获得超3个赞
编译器(VC2012)提升为可以容纳值的“最小”整数。在第一种情况下,signed int(和long int)不能(在应用符号之前),但是unsigned int可以:2147483648具有unsigned int ???? 类型。在第二秒中,您int从强制unsigned。
const bool i= (-2147483648 > 0) ; // --> true
警告C4146:一元减运算符应用于无符号类型,结果仍为无符号
以下是相关的“好奇心”:
const bool b= (-2147483647 > 0) ; // false
const bool i= (-2147483648 > 0) ; // true : result still unsigned
const bool c= ( INT_MIN-1 > 0) ; // true :'-' int constant overflow
const bool f= ( 2147483647 > 0) ; // true
const bool g= ( 2147483648 > 0) ; // true
const bool d= ( INT_MAX+1 > 0) ; // false:'+' int constant overflow
const bool j= ( int(-2147483648)> 0) ; // false :
const bool h= ( int(2147483648) > 0) ; // false
const bool m= (-2147483648L > 0) ; // true
const bool o= (-2147483648LL > 0) ; // false
C ++ 11标准:
2.14.2整数文字[lex.icon]
…
整数文字是没有句号或指数部分的数字序列。整数文字可以具有指定其基数的前缀和指定其类型的后缀。
…
整数文字的类型是相应列表中可以表示其值的第一个。
如果整数文字不能用其列表中的任何类型表示,并且扩展整数类型(3.9.1)可以表示其值,则它可能具有该扩展整数类型。如果文字列表中的所有类型均已签名,则扩展整数类型应被签名。如果文字列表中的所有类型都是无符号的,则扩展整数类型应为无符号的。如果列表同时包含有符号和无符号类型,则扩展整数类型可以是有符号或无符号的。如果程序的翻译单元之一包含不能用任何允许的类型表示的整数文字,则该程序格式错误。
这些是标准中整数的促销规则。
4.5整体促销 [conv.prom]
以外的整数类型的prvalue bool,char16_t,char32_t,或 wchar_t,其整数转换秩(4.13)小于INT的秩可以被转换成类型的prvalue int如果int可以表示源类型的所有值; 否则,可以将源prvalue转换为type的prvalue unsigned int。
TA贡献1829条经验 获得超7个赞
由于-2147483648实际上对其应用2147483648了否定(-),因此该数字不是您所期望的。它实际上等效于此伪代码:operator -(2147483648)
现在,假设您的编译器具有sizeof(int),4并且CHAR_BIT被定义为8,则将使2147483648溢出成为整数(2147483647)的最大有符号值。那么最大加一是多少?让我们用一个4位2s的补码整数来计算。
等待!8溢出整数!我们做什么?使用其无符号表示形式1000并将这些位解释为有符号整数。这种表示方式使我们得以-8应用2s补码求反,导致8,众所周知,它大于0。
这就是为什么<limits.h>(和<climits>)通常定义INT_MIN为((-2147483647) - 1)-,从而使最大有符号整数(0x7FFFFFFF)取反(0x80000001),然后递减(0x80000000)。
- 3 回答
- 0 关注
- 345 浏览
添加回答
举报