1

Why this the result of this program negative, despite having used the long long int data type? Please help me. My code is below:

#include <iostream>

#define percent 10

int main() {
    int A=200,B=400,C=150,D=210;
    long long int non_Zero_value_number;
    non_Zero_value_number=(percent*(A*B*C*D))/100;
    std::cout<< "Number of  value 10% = " << non_Zero_value_number << std::endl;
}
Yun
  • 3,056
  • 6
  • 9
  • 28
  • `(percent*(A*B*C*D))/100` is of type `int`. Only after doing all calculations (and after possible overflow) the result is converted to `long long int` – Gerhardh Sep 01 '21 at 13:56
  • How Can I solve this problem – Safayet Hossain Sobuj Sep 01 '21 at 13:59
  • Instead of `long long int`, use `int64_t`. Then you and others looking at the code know *exactly* the type of integer that is being used, the integer's size, etc. – PaulMcKenzie Sep 01 '21 at 14:12
  • @PaulMcKenzie -- but `long long` is required to be at least 64 bits. The problem here isn't the size of the result; it's the size of the operands. Changing `long long int` to `int64_t` won't fix that. – Pete Becker Sep 01 '21 at 14:42

4 Answers4

4

The numbers 10 and 100 are integer literals and A, B, C and D are of the type int. This means that the expression (percent*(A*B*C*D))/100 will use the int type and since the result does not fit into this type, the behavior is undefined:

When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined, — the possible manifestations of such an operation include:

  • it wraps around according to the rules of the representation (typically 2's complement),
  • [...]

It appears that this happened with the given program, resulting in a negative number. It is possible to cast one of the involved variables to a long long int and rely on integer conversions and the specific operator precedences for the expression to avoid the overflow, but it is better to avoid this altogether and to declare/define the variables/values used in the expression as long long int's. Use the LL suffix to define a long long int integer literal (C++11).

Code example (some refactoring applied):

#include <iostream>

#define PERCENT 10LL

int main()
{
    long long int A=200,B=400,C=150,D=210;
    long long int non_zero_value_number=(PERCENT*(A*B*C*D))/100LL;
    std::cout << "Number of  value 10% = " << non_zero_value_number << '\n';
}
Yun
  • 3,056
  • 6
  • 9
  • 28
1

If you're sure that the variables will always take positive integers then you can just use unsigned long long int as shown in the below program. As you named a variable non_Zero_value_number, this makes sense.

#include<iostream>
#include<vector>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <sstream>
#define percent 10

using namespace std;

int main () {


    srand((unsigned) time(0));

unsigned long long int A=200,B=400,C=150,D=210,E=50,F=30;
   unsigned long long int non_Zero_value_number;
        non_Zero_value_number=(percent*(A*B*C*D))/100;
        cout<< "Number of  value 10% = " << non_Zero_value_number<<endl;
  return 0;
}
Jason
  • 36,170
  • 5
  • 26
  • 60
0

You should declare you other ints as long long int as well.

The calculation (A * B * C * D) returns a negative number as they are all regular integers and the result overflows int. This should fix it:

long long int A=200,B=400,C=150,D=210,E=50,F=30;

Also, while not technically incorrect, typically #define variables are all caps so it's clear where they come from. At first glance I thought to myself, "where do they declare percent?"

#define PERCENT 10

Then of course you'll also have to change:

non_Zero_value_number=(PERCENT *(A*B*C*D))/100;
Sean
  • 49
  • 4
-1

You either need to declare one of the variables you're multiplying as a long or you need to cast it to long during the multiplication.

Declaring 1 variable as a long: long A = 200; int B = 400, C=150, D=210, ...

Declaring all variables as long: long A = 200, B = 400, C=150, D=210, ...

Casting variable A to long during multiplication: non_Zero_value_number=(percent*((long) ABC*D))/100;

The problem is that C++ is doing all of the calculations in int before turning the end-result into a long. Which means that you still have to deal with the int overflow once the int value exceeds 2147483647 (see https://learn.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)

Since 10 x 200 x 400 x 150 x 210 = 25200000000, you are exceeding the limits of int by several orders of magnitude

Note: This question is very similar to the one in the link (although for C++ instead of C#): Multiplying int with long result c#

Timothy K
  • 39
  • 4
  • "Declaring/casting _one_ variable as `long`" is *not* a correct general solution. Depending on the associativity of the operators and the exact moment of overflow, this may still produce undefined behavior. In this example, it only happens to work because the left-most variable was chosen to be a `long int` and the `*` operator has left-to-right associativity. – Yun Sep 01 '21 at 15:49
  • Besides that, the casting example is missing some `*` characters and uses a C-style cast which is better replaced by a C++ `static_cast`. – Yun Sep 01 '21 at 15:58