【问题标题】:Integer overflow and integer limits整数溢出和整数限制
【发布时间】:2016-08-05 17:38:12
【问题描述】:

我是新手,请帮助我理解 INTEGER OVERFLOW 并在以下示例的上下文中使用 INTEGER LIMITS。 我无法解释以下代码的输出。 我考虑了三种情况,直接打印,整数和无符号长整数。

#include<iostream>
#include<limits.h>
using namespace std;

int main()
{
int tmp1=0,tmp2=0,tmp3=0,tmp4=0;
unsigned long long temp1=0,temp2=0,temp3=0,temp4=0;

cout<<"Directly printing"<<endl;

cout<<-2*INT_MIN<<endl<<2*INT_MIN<<endl<<-2*INT_MAX<<endl<<2*INT_MAX<<endl;

cout<<"Using integer"<<endl;

tmp1 = -2*INT_MIN;
tmp2 = 2*INT_MIN;
tmp3 = -2*INT_MAX;
tmp4 = 2*INT_MAX;

cout<<temp1<<endl<<tmp2<<endl<<tmp3<<endl<<tmp4<<endl;

cout<<"Using unsigned long long variables"<<endl;

temp1 = -2*INT_MIN;
temp2 = 2*INT_MIN;
temp3 = -2*INT_MAX;
temp4 = 2*INT_MAX;

cout<<temp1<<endl<<temp2<<endl<<temp3<<endl<<temp4;
}

输出:

Directly printing
0
0
2
-2
Using integer
0
0
2
-2
Using unsigned long long variables
0
0
2
18446744073709551614

【问题讨论】:

  • &lt;limits.h&gt; 是 C 头文件,这并不重要,但您可能想看看 &lt;limits&gt; 有例如std::numeric_limits&lt;int&gt;::max()
  • 您的代码中有未定义的行为,您在初始化之前使用unsigned long long 变量。在“使用整数”部分,您打印 temp1 等的值,而您应该使用 tmp1 等。尝试使用更好的变量命名,希望这些事情不会发生太多。此外,一个好的编译器会对此发出警告。
  • 听起来很像“为我做作业”。到目前为止,您发现了哪些相关事实?具体有什么不明白的?输出中是否有任何特别让您感到意外的东西? C++ 标准草案文件很容易在线获得——您是否尝试了解有关溢出期间的限制或行为的任何信息?即使这太令人生畏,也可以在 S.O. 上研究具体问题。
  • 我无法理解输出。如果您对 C++ 标准论文有一些参考,请分享它们

标签: c++ integer overflow limits


【解决方案1】:

tmp1 = -2*INT_MIN; 未定义的行为,除非 INT_MAX 的大小是 INT_MIN 的两倍(它不会)。

tmp2 = 2*INT_MIN; 未定义行为(溢出有符号整数)

tmp3 = -2*INT_MAX; 未定义的行为,除非 INT_MIN 的大小是 INT_MAX 的两倍(它不会)。

tmp4 = 2*INT_MAX; 未定义行为(溢出有符号整数)

temp1 = -2*INT_MIN; 未定义行为(溢出有符号整数)

temp2 = 2*INT_MIN; 未定义行为(溢出有符号整数)

temp3 = -2*INT_MAX; 未定义行为(溢出有符号整数)

temp4 = 2*INT_MAX; 未定义行为(溢出有符号整数)

【讨论】:

  • “无符号类型的有符号算术”只是将有符号值提升为无符号,不是吗?这不是很好定义 ([conv.integral] ) 吗?
  • @user2079303 你是对的。 gcc 给我“25:警告:表达式 [-Woverflow] 中的整数溢出”。
  • 确实,这些行具有相同的未定义行为,即在乘法中溢出有符号整数,如上面的行。 INT_MAX2 都已签名。
  • 我认为最后一点有点多余。所有带符号的乘法都溢出(不存在的极端情况中的-2*INT_MAX 除外)并具有UB。无论有符号整数是否在可表示的范围内,所有对无符号的赋值都将得到很好的定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 2022-01-07
相关资源
最近更新 更多