溢流/下溢问题

Overflow/Underflow issues?

本文关键字:问题 下溢 溢流      更新时间:2023-10-16

我应该在写一个可以将十进制数转换为二进制数的程序。我有转换工作的代码,但是当我尝试在用户输入超出我的类型(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)

,其中bigNumberunsigned 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 ),例如