为了账号安全,请及时绑定邮箱和手机立即绑定

(-2147483648> 0)在C ++中返回true吗?

(-2147483648> 0)在C ++中返回true吗?

C++
繁花不似锦 2019-12-06 07:06:20
-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。我糊涂了。谁能解释一下?更新02-05-2012:感谢您的评论,在我的编译器中,int的大小为4个字节。我正在使用VC进行一些简单的测试。我已经更改了问题的描述。在这篇文章中,这得到了很多很好的答复,AndreyT给出了关于编译器将如何对此类输入进行操作以及如何实现此最小整数的非常详细的解释。另一方面,qPCR4vir提供了一些相关的“好奇心”以及整数的表示方式。好厉害!
查看完整描述

3 回答

?
慕桂英4014372

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

后者将无法按预期工作。



查看完整回答
反对 回复 2019-12-07
?
Helenr

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]



整数文字是没有句号或指数部分的数字序列。整数文字可以具有指定其基数的前缀和指定其类型的后缀。



整数文字的类型是相应列表中可以表示其值的第一个。

//img1.sycdn.imooc.com//5db00ce10001b88804320321.jpg

如果整数文字不能用其列表中的任何类型表示,并且扩展整数类型(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。



查看完整回答
反对 回复 2019-12-07
?
吃鸡游戏

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)。



查看完整回答
反对 回复 2019-12-07
  • 3 回答
  • 0 关注
  • 345 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信