0

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?

  • What are you seeing as output? "I don't get any result" can mean many things. – Human-Compiler Jan 23 '21 at 03:18
  • `num_1 + num_2` this is the sum of two `long`s, and is calculated as a `long`. By the time you assign the result to a `long long` the overflow has already happened (assuming 32-bit `long` type). Use `(long long)num_1 + num_2` to force the addition to be done as `long long`. – dxiv Jan 23 '21 at 03:19
  • It would appear you are on a 32-b9t platform where `long` is 4-bytes with a range of `-2147483648` to `2147483647` – David C. Rankin Jan 23 '21 at 03:19
  • i do not get any error output : `El resultado es 4294967300` try checking if you are compiling properly – Jaysmito Mukherjee Jan 23 '21 at 03:21
  • Literally just a blank space – Sofía González Jan 23 '21 at 03:21
  • @SofíaGonzález Add `<< endl` at the end. – dxiv Jan 23 '21 at 03:22
  • There is no *signed* integer overflow -- it is undefined behavior you are seeing. Always ***Validate*** EVERY user input, e.g `if (!(cin>>num_1>>num_2)) { cerr << "error: invalid long input.\n"; return 1; }` – David C. Rankin Jan 23 '21 at 03:22
  • 2
    A `long` is only guaranteed able to represent values in the range `-2147483647` to `2147483647` inclusive. The two values you are entering are outside that range. Also, `long long suma = num_1 + num_2` calculates `num_1 + num_2` as a `long` (which limits the result to being in the range supported by a `long`, and causes undefined behaviour if the result cannot be represented by a `long`) and THEN converts the result of addition `long long`. Since you have inputs (or the sum of inputs) that are outside the range that a `long` can represent, the behaviour of your program is undefined. – Peter Jan 23 '21 at 03:29
  • @DavidC.Rankin "*Overflow*" is usually taken to mean outside "*the range of representable values for its type*". So something like `INT_MAX + 1` is *both* a signed integer overflow *and* undefined behavior. – dxiv Jan 23 '21 at 03:33
  • @dxiv - agreed. It is the limit of what can be stored. The overflow check must occur before the sum is computed to prevent the error. The input must also be checked to catch the failed input if it exceeds the limit of type. – David C. Rankin Jan 23 '21 at 03:53
  • @DavidC.Rankin: Doesn't have to be 32 bit platform; Windows still has 32 bit `long`s even on 64 bit Windows. – ShadowRanger Jan 23 '21 at 04:01
  • Ouch, I wasn't even thinking of the Windows issue. Thanks. – David C. Rankin Jan 23 '21 at 04:02

3 Answers3

2

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.\n";
         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.\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";
}

(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.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

You need to change num_1 and num_2 to be long long as well like this:

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;

}
Illusion705
  • 451
  • 3
  • 13
0
#include <cmath>
#include <iostream>

using namespace std;

int main() {
  string s1, s2;
  int d = 0;
  cin >> s1 >> s2;
  if (s1.size() == s2.size()) {
    int arr[s1.size() + 1];
    for (int i = s1.size() - 1; i >= 0; i--) {
      if ((s1[i] - '0' + (s2[i] - '0')) % 10 + d > 9) {
        arr[i + 1] = ((s1[i] - '0' + (s2[i] - '0')) % 10 + d) % 10;
        d = 1;
      } else {
        arr[i + 1] = (s1[i] - '0' + (s2[i] - '0')) % 10 + d;
        d = (s1[i] - '0' + (s2[i] - '0')) / 10;
      }
    }
    arr[0] = d;
    if (arr[0] == 0) {
      for (int i = 1; i < s1.size() + 1; i++)
        cout << arr[i];
    } else {
      for (int i = 0; i < s1.size() + 1; i++)
        cout << arr[i];
    }
  } else if (s1.size() > s2.size()) {
    int arr[s1.size()];
    for (int i = s2.size() - 1; i >= 0; i--) {
      if ((s1[s1.size() - s2.size() + i] - '0' + (s2[i] - '0')) % 10 + d > 9) {
        arr[i + s1.size() - s2.size()] =
            ((s1[s1.size() - s2.size() + i] - '0' + (s2[i] - '0')) % 10 + d) %
            10;
        d = 1;
      } else {
        arr[i + s1.size() - s2.size()] =
            (s1[s1.size() - s2.size() + i] - '0' + (s2[i] - '0')) % 10 + d;
        d = (s1[s1.size() - s2.size() + i] - '0' + (s2[i] - '0')) / 10;
      }
    }
    if (d == 1) {
      for (int i = s1.size() - s2.size() - 1; i >= 0; i--) {
        if ((s1[i] - '0') % 10 + d > 9) {
          arr[i] = ((s1[i] - '0') % 10 + d) % 10;
          d = 1;
        } else {
          arr[i] = (s1[i] - '0') % 10 + d;
          d = (s1[i] - '0') / 10;
        }
      }
      if (d == 1) {
        cout << 1;
        for (int i = 0; i < s1.size(); i++)
          cout << arr[i];
      } else {
        for (int i = 0; i < s1.size(); i++)
          cout << arr[i];
      }
    } else {
      for (int i = 0; i < s1.size() - s2.size() ; i++) cout << s1[i];
      for (int i = s1.size() - s2.size(); i < s1.size(); i++) cout << arr[i];
    }
  } else if (s1.size() < s2.size()) {
    int arr[s2.size()];
    for (int i = s1.size() - 1; i >= 0; i--) {
      if ((s2[s2.size() - s1.size() + i] - '0' + (s1[i] - '0')) % 10 + d > 9) {
        arr[i + s2.size() - s1.size()] =
            ((s2[s2.size() - s1.size() + i] - '0' + (s1[i] - '0')) % 10 + d) %
            10;
        d = 1;
      } else {
        arr[i + s2.size() - s1.size()] =
            (s2[s2.size() - s1.size() + i] - '0' + (s1[i] - '0')) % 10 + d;
        d = (s2[s2.size() - s1.size() + i] - '0' + (s1[i] - '0')) / 10;
      }
    }
    if (d == 1) {
      for (int i = s2.size() - s1.size() - 1; i >= 0; i--) {
        if ((s2[i] - '0') % 10 + d > 9) {
          arr[i] = ((s2[i] - '0') % 10 + d) % 10;
          d = 1;
        } else {
          arr[i] = (s2[i] - '0') % 10 + d;
          d = (s2[i] - '0') / 10;
        }
      }
      if (d == 1) {
        cout << 1;
        for (int i = 0; i < s2.size(); i++)
          cout << arr[i];
      } else {
        for (int i = 0; i < s2.size(); i++)
          cout << arr[i];
      }
    } else {
      for (int i = 0; i < s2.size() - s1.size() ; i++) cout << s2[i];
      for (int i = s2.size() - s1.size(); i < s2.size(); i++) cout << arr[i];
    }
  }
  return 0;
}
  • Please don't answer with just code; explain what your code does and how it solves the problem. Check this before writing an answer: https://stackoverflow.com/help/how-to-answer . Good luck. – Usitha Indeewara Nov 05 '22 at 10:03