Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.9k views
in Technique[技术] by (71.8m points)

c++ - Trying to sum two large large numbers and don't get a result¡

I'm new to c++. My teacher left us to do some "tricky" exercises. On this we have to make the sum of two numbers, the trick here is that the maximum value of each int has to be 2 147 483 650 max, so the result would have to be a long long type (I think)

I'm trying to experiment with this and came out with this result:

   #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;

}

The platform says its incorrect, after testing it I realized that when I input 2147483650 + 2147483650 I don't get any result. Why? Am I understanding something wrong?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are two issues you are running into. This applies to a 32-bit architecture where the range of long is:

-2147483647 to 2147483647
  1. Your input attempt with cin>>num_1>>num_2; fails for values larger than 2147483647 or smaller than -2147483647 -- but you do not catch that because you fail to check the stream state after the attempted input. You would catch the invalid input with:

     if (!(std::cin >> num_1 >> num_2)) {                /* validate EVERY input */
         std::cerr << "error: invalid long input.
    ";
         return 1;
     }
    
  2. If your the sum of num_1 and num_2 exceeds the range of values that can be stored in a long (4-bytes on most 32-bit architectures) Undefined Behavior results and your program could appear to work normally, crash or anything in between. To ensure there is no overflow in the sum, you must check the result against the limits of the values that can be stored in long.

A simple method is:

/* 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;
}

(See: std::numeric_limits for details on use for obtaining limits for all common types)

The function will return false if the value cannot be added safely, or return true filling the reference sum if the value can be added safely.

Putting it altogether, you could do:

#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.
";
        return 1;
    }
    
    if (safe_sum_long (suma, num_1, num_2))                 /* valid sum */
        std::cout << "El resultado es " << suma << '
';
    else
        std::cerr << "error: overflow occurs in sum.
";
}

(note: you will want to review Why is “using namespace std;” considered bad practice?)

Example Use/Output

Valid input:

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

Valid input but overflow in result:

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

Invalid input:

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

While you do not tell us what architecture you are running on, I'm 99% sure you are running in to the limits of long on your system. If you need to work with the the larger number, use a larger type for num_1 and num_2. Either way, you should still check whether the sum can be done without error. Let me know if you have further questions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...