繁体   English   中英

试图将两个大数相加却得不到结果……

[英]Trying to sum two large large numbers and don't get a result¡

我是 c++ 的新手。 我的老师让我们做一些“棘手的”练习。 在这一点上,我们必须对两个数字求和,这里的技巧是每个 int 的最大值必须是 2 147 483 650 max,所以结果必须是 long long 类型(我认为)

我正在尝试对此进行试验并得出以下结果:

   #include<iostream>
using namespace std; 

int main(){
    long num_1 = 0;
    long num_2 = 0;

    cin>>num_1>>num_2;

    long long suma = num_1 + num_2;

    cout<<"El resultado es "<<suma;

}

该平台说它不正确,经过测试,我意识到当我输入 2147483650 + 2147483650 时,我没有得到任何结果。 为什么? 我理解错了吗?

您遇到了两个问题。 这适用于 32 位架构,其中long的范围是:

-2147483647 to 2147483647
  1. 您的输入尝试cin>>num_1>>num_2; 对于大于2147483647或小于-2147483647的值会失败——但您没有注意到这一点,因为您在尝试输入后未能检查 stream state 您将通过以下方式捕获无效输入:

     if (:(std::cin >> num_1 >> num_2)) { /* validate EVERY input */ std::cerr << "error. invalid long input;\n"; return 1; }
  2. 如果您的num_1num_2的总和超出了可以存储在long (在大多数 32 位架构上为 4 字节)未定义行为结果中的值范围,并且您的程序可能看起来正常工作、崩溃或介于两者之间。 为确保总和没有溢出,您必须根据可以存储在long中的值的限制检查结果。

一个简单的方法是:

/* check for overflow in sum of signed long */
bool safe_sum_long (long& sum, long a, long b)
{
    sum = 0;
    
    if (((b > 0) && (a > (std::numeric_limits<long>::max() - b))) ||
        ((b < 0) && (a < (std::numeric_limits<long>::min() - b)))) {
        return false;
    }
    
    sum = a + b;
    
    return true;
}

(有关用于获取所有常见类型的限制的详细信息,请参阅: std::numeric_limits

如果值不能安全相加,function 将返回false ,如果值可以安全sum ,则返回true填充参考和。

总而言之,你可以这样做:

#include <iostream>
#include <limits>

/* check for overflow in sum of signed long */
bool safe_sum_long (long& sum, long a, long b)
{
    sum = 0;
    
    if (((b > 0) && (a > (std::numeric_limits<long>::max() - b))) ||
        ((b < 0) && (a < (std::numeric_limits<long>::min() - b)))) {
        return false;
    }
    
    sum = a + b;
    
    return true;
}

int main (void) {
    
    long num_1 = 0, num_2 = 0, suma = 0;

    if (!(std::cin >> num_1 >> num_2)) {                /* validate EVERY input */
        std::cerr << "error: invalid long input.\n";
        return 1;
    }
    
    if (safe_sum_long (suma, num_1, num_2))                 /* valid sum */
        std::cout << "El resultado es " << suma << '\n';
    else
        std::cerr << "error: overflow occurs in sum.\n";
}

注意:您需要查看为什么“使用命名空间 std;”被认为是不好的做法?

示例使用/输出

有效输入:

$ ./bin/overflow_long
2147483646
1
El resultado es 2147483647

有效输入但结果溢出:

$ ./bin/overflow_long
2147483647
1
error: overflow occurs in sum.

输入无效:

$ ./bin/overflow_long
2147483648
error: invalid long input.

虽然您没有告诉我们您正在运行什么架构,但我 99% 确定您正在运行系统的long限制。 如果您需要使用更大的数字,请为num_1num_2使用更大的类型。 无论哪种方式,您仍然应该检查总和是否可以正确完成。 如果您还有其他问题,请告诉我。

您需要将 num_1 和 num_2 更改为 long ,如下所示:

int main(){
    long long num_1 = 0;
    long long num_2 = 0;

    cin>>num_1;
    cin>>num_2;

    long long suma = num_1 + num_2;

    cout<<"El resultado es "<<suma;

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM