-2147483648是32位整数类型的最小整数,但它似乎会在if(…)中溢出
句子:
if (-2147483648 > 0)
std::cout << "true";
else
std::cout << "false";
这将在我的测试中打印
true
。但是,如果我们将-2147483648转换为整数,结果将不同:
if (int(-2147483648) > 0)
std::cout << "true";
else
std::cout << "false";
这将打印
false
。
我很困惑。有人能解释一下吗?
更新日期:2012年5月2日:
感谢您的评论,在我的编译器中,int的大小是4字节。我使用VC进行一些简单的测试。我改变了问题中的描述。
在这篇文章中,有很多非常好的回复,AndreyT对编译器在这样的输入上的行为以及这个最小整数是如何实现的给出了非常详细的解释。qPCR4vir另一方面给出了一些相关的“好奇心”以及整数是如何表示的。太令人印象深刻了!
简而言之,2147483648
溢出到-2147483648
,和(-2147483648)
这就是
2147483648
在二进制中的样子。
此外,在有符号二进制计算的情况下,最高有效位(“MSB”)是符号位。这个问题可能有助于解释原因。
编译器(VC2012)提升到可以保存值的“最小”整数。在第一种情况下,有符号的int
(和long int
)不能(在应用符号之前),但是无符号的int
可以:2147483648
有无符号的int
???类型。在第二种情况下,您强制int
从无符号
。
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]
如果int
可以表示源类型的所有值,则除bool
、char16\u t
、char32\u t
或wchar\u t
以外的整数类型的PR值(其整数转换秩(4.13)小于int秩)可以转换为int
类型的PR值;否则,可以将源prvalue转换为类型为unsigned int
的prvalue。
-2147483648
不是数字。C语言不支持负值。
-2147483648
实际上是一个表达式:一个正文本值2147483648
,前面有一元-
运算符。值2147483648
对于平台上int
范围的正面来说显然太大。如果类型long int
在您的平台上具有更大的范围,则编译器必须自动假定2147483648
具有long int
类型。(在C 11中,编译器还必须考虑<代码> long long int /Cux>类型)。这将使编译器在较大类型的域中计算-2147483648
,结果将是负数,正如人们所期望的那样。
但是,显然在您的情况下,long int
的范围与int
的范围相同,并且通常在您的平台上没有大于int
范围的整数类型。这正式意味着正常量2147483648
溢出所有可用的有符号整数类型,这反过来意味着程序的行为未定义。(语言规范在这种情况下选择未定义的行为,而不需要诊断消息,这有点奇怪,但事实就是这样。)
实际上,考虑到行为是未定义的,2147483648
可能被解释为某个依赖于实现的负值,该负值在应用一元-
后恰好变为正值。或者,一些实现可能会决定尝试使用无符号类型来表示值(例如,在C89/90中,编译器需要使用无符号长整型
,但在C99或C中则不需要)。实现可以做任何事情,因为行为是未定义的。
作为旁注,这就是为什么像INT\u MIN
这样的常量通常被定义为
#define INT_MIN (-2147483647 - 1)
而不是看起来更直截了当的
#define INT_MIN -2147483648
后者不会如预期的那样发挥作用。
问题内容: 我有这样的事情: 而且我总是得到“时钟周期为:0-0”的输出 知道为什么会这样吗? (仅给出一点点细节,something_else()函数使用蒙哥马利表示法执行从左到右的求幂运算,而且我不确定不确定something_else()函数确实花费了一些不可忽略的时间。) 这是在Linux上。uname -a的结果是: 问题答案: 该功能不测量CPU时钟周期。 C说: “ 从实现定义的仅与
问题内容: 我的一个朋友以这种奇怪的行为来到我这里,我无法解释,任何见解的观点都将不胜感激。 我正在运行VS 2005(C#2.0),以下代码显示了该行为 上面的代码,打印“ 0”,清楚地表明它应该有返回-1 这在Java中也会发生,其中以下类显示了该行为: 我正在运行Java 1.6.0_17 问题答案: 这不是规则的例外,而是方法和定义的自然结果。 您声称应该返回。这基本上等于应返回的索赔。为
问题内容: 我得到imageView的宽度0。下面是代码。 xml文件: 活动内容: 我不想使用下面的代码,因为我需要将此代码放置在很多地方。 我的解决方法: 实际上,我以后不需要在活动中添加此代码。我将其添加到非活动类中,而不是ImageView的宽度,而是使用了位图图像的宽度,现在没有此问题。 问题答案: 您在哪里打电话并在ImageView上打电话?如果您是在活动中打电话,则无法使用。您需要
问题内容: 我知道有很多标题相同的主题。但是大多数情况是将查询插入了错误的位置。但是我认为我说对了。所以问题是,即使将数据插入数据库,我仍然会得到0。有人知道我可能是错的答案吗? 这是我的代码: 在此先多谢一遍,因为我几乎已经整整一天都为此而努力。(可能有点小而愚蠢) 问题答案: 根据手册 mysql_insert_id返回: 成功执行前一个查询为AUTO_INCREMENT列生成的ID; 如果前
问题内容: 我有这个测试表: 使用这三个插入 并发行 但是查询始终会导致。 PHP ,也没有结果。 我整天都在玩弄,无法正常工作。有想法吗? 问题答案: 问题似乎出在MySQL的phpmyadmin配置文件中,每次发出查询时都会生成新的phpmyadmin配置文件- 因此使其无效。 后续主题中的更多信息每个查询都会创建一个新的CONNECTION_ID() 也感谢dnagirl的帮助
问题内容: 在Python 2.6中查看Queue.py时,我发现这个结构有点奇怪: 如果maxsize为0,则队列永远不会满。 我的问题是在这种情况下如何运作?如何0 < 0 == 0被认为是错误的? 问题答案: 我相信Python对关系运算符的序列有特殊的处理方式,以使范围比较易于表达。能说比说好得多。 这些称为链接比较。这是他们文档的链接。 在您谈论的其他情况下,括号会强制在一个关系运算符之