溢流/下溢问题
Overflow/Underflow issues?
我应该在写一个可以将十进制数转换为二进制数的程序。我有转换工作的代码,但是当我尝试在用户输入超出我的类型(unsigned short)的最大/最小值时发送错误时,使用if/else语句。当我输入一个应该是无效的数字时,程序跳转到转换语句,要么打印最大二进制数(如果输入超过655355),要么从最大值向下计数(如果输入负数)。
我想我写的都是正确的。
#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
// This converts the number to binary, it divides the imputed number by two, printing the reminders//
void bin(unsigned short nub)
{
if (nub <=1)
{
cout << nub;
return;
}
unsigned short rem;
rem = nub % 2;
bin( nub / 2);
cout << rem;
}
int main()
{
unsigned short dd;
unsigned short bigNumber = pow(2,sizeof(unsigned short)*8)-1;
cout << "nPlease enter an unsigned short int between 0 and " << bigNumber << ": ";
cin >> dd;
//Should be printed if user imputs a number larger than the data type//
if ( dd > bigNumber )
{
cout << "nThe number is invalid. Please try again.nn";
}
//Should be printed if user imputs a negative number//
else if (dd < 0)
{
cout << "nThe number is invalid. Please try again.nn";
}
//Prints the binary number//
else
{
cout << "nThe Binary version of " << dd << " is ";
bin(dd);
cout << endl << endl;
}
return 0;
}
您自己也遇到了溢出。为dd
使用另一种能够保存大于65535的值的数据类型(例如unsigned int)。
你有溢出问题,特别是从无符号数
这是你的第一个问题:
unsigned short dd;
// ...
else if (dd < 0)
你已经声明dd
是无符号的,所以这是一个没有意义的比较。
下一步,你已经完成了
if(dd > bigNumber)
,其中bigNumber
是unsigned short
所能容纳的最大值。同样,这是一个毫无意义的比较。为了解决这个问题,你需要让dd
成为一个更大的数据类型;为什么不用unsigned int
呢?
最后,一个样式提示。在<climits>
中可以找到USHRT_MAX
,而不是可怕的pow(2,sizeof(unsigned short)*8)-1
装置。
问题是您正在比较已经溢出的值dd
。它永远不会超过它所能容纳的最大值。
正如其他人建议的那样,你可以为dd
使用更大的数据类型,但在某些情况下,这也会导致'无声'溢出。
假设输入的值足够大,甚至溢出unsigned int
(或任何其他)。你也会遇到同样的问题。不经常,但你会有。
没有简单的方法可以防止,你可以检查这个问题的答案,你如何做到这一点
如果输入对于数据类型来说太大,那么流将进入失败状态。因此您可以检查故障状态。你现有的代码没有做到这一点;在这种情况下,它将对未初始化的变量dd
中的垃圾执行bin
。
下面是一些示例代码,实际上使用了一个循环(你的代码说"Please try again"然后退出!):
for (;;)
{
cout << "Please enter a number between 0 and " << USHRT_MAX << ": ";
cin >> dd;
if ( !cin )
{
if ( cin.eof() )
break; // exit loop entirely if the input is closed
cout << "Not a valid unsigned short, please try againn";
cin.clear(); // cancel the failure state
string s; getline(cin, s); // discard rest of line
continue;
}
cout << "The Binary version of " << dd << " is ";
bin(dd);
cout << endl;
break;
}
如果你想使用比0
更有限的范围…USHRT_MAX
可以将if ( !cin )
修改为if ( !cin || dd < 12345 )
,例如
- 自定义 std::fstream,std::filebuf 的溢出和下溢函数未为每个字符调用
- 带有剪裁下溢的夏亚减法
- 使用 size_t 初始化循环变量时的整数下溢
- 无锁队列实现中的虚假下溢C++
- 在减法期间将 C++ 转换为字节 (unit8_t) 不会像我预期的那样强制下溢;输出int16_t;为什么?
- C++长 int 溢出/下溢
- 上溢/下溢是执行时未定义的行为吗
- C++ 在将字符串提取到标量时处理溢出/下溢
- C/FORTRAN将双下溢设置为零
- basic_streambuf炒锅的功能溢出和下溢如何
- 为什么C++下溢/溢出行为被视为未定义
- C++下溢和溢出
- 渐变下溢程序的表示
- 指针下溢或溢出时会发生什么情况
- 溢流/下溢问题
- 如何在C语言中检测浮点下溢
- 如何检测双精度浮点溢出和下溢
- 未签名的下溢机制
- 编译器构造-如何在C++中发生堆栈下溢
- 将std::string转换为integer时,如何处理上溢/下溢