Reputation: 33
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;
}
Upvotes: 1
Views: 1604
Reputation: 3812
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';
}
Upvotes: 4
Reputation: 39
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#
Upvotes: -1
Reputation: 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;
}
Upvotes: 1
Reputation: 49
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;
Upvotes: 0