Nhan Phan
Nhan Phan

Reputation: 1302

Multiply 2 large numbers in C++ have wrong result

There are 2 large integer numbers. When I multiply it the result is always wrong, even if I used long double and the result should be in valid range of long double:

long double f = 1000000000 * 99999;

I debugged, and the result is so strange: -723552768.00000000. Did I missed something? how can I multiple it?

Thanks and regard!

Upvotes: 0

Views: 5499

Answers (5)

Christopher Conroy
Christopher Conroy

Reputation: 21

Numeric literals are int by default in C++. Thus, the expression 1000000000 * 99999 is viewed as the multiplication of two int 's and therefore the result returned by the * operator is an int. This int is only converted to the long double variable f after the multiplication has taken place. Depending on your platform, the range of int is usually from -2147483648 to 2147483647 (or 4 bytes in size). However, the product of 1000000000 x 99999 is 9.9999 x 10^13 which falls outside this range and thus overflow occurs as the int variable is not large enough to hold the value.

To avoid this, at least one of the numbers the * operator operates on should be declared as a long double literal with the suffix .l or .L as follows:

long double f = 1000000000.L * 99999

In the above expression , the * operator will return a long double which is large enough to hold the resulting product before being assigned to f.

Upvotes: 2

user10237405
user10237405

Reputation:

1000000000 and 99999 are integer numbers, then the result of 1000000000 * 99999 will be an integer before it is assigned to your variable, and the result is out of range of integer.

You should make sure that the result is a long double first:

long double f = (long double) 1000000000 * 99999;

Or

long double f = 1000000000LL * 99999;

Upvotes: 0

Michael Veksler
Michael Veksler

Reputation: 8475

Actually you invoke undefined behavior with:

long double f = 1000000000 * 99999;

First, evaluate 1000000000 * 99999, which is a multiplication of two int objects. Multiplying two int objects is always an int. Since int is not big enough to represent the result (most likely 32 bits), the upper bits are lost.

Since overflows in signed integer types is undefined, you just triggered undefined behavior. But in this case it is possible to explain what happened, even though it is UB.

The computation keeps only the lowest 32 bits, which should be (1000000000 * 99999) modulo (2**32) == 3571414528. But this value is too big for int. Since on PC int negatives are represented by two's complement, we have to subtract 2**32, every time 2**31<= result < 2**32. This gives -723552768

Now, the last step is:

long double f = -723552768

And that is what you see.

To overcome the issue, either use long long like this:

long double f = 1000000000LL * 99999;

Or double:

long double f = 1000000000.0 * 99999;

Upvotes: 1

Seek Addo
Seek Addo

Reputation: 1893

from the C++ standards:

4 An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double

auto fl = 1000000000.L * 99999.L;
std::cout << fl << "\n";

or

long double fl = 1000000000L * 99999.L;
std::cout <<"\n"<< fl << "\n";

Upvotes: 4

Saboor
Saboor

Reputation: 352

Agree with @feiXiang. You are basically multiplying two ints. To do correct calculations, you have to define large numbers as long double. See the code below:

 #include <iostream>

using namespace std;

int main()
{
    long double a = 1000000000;
    long double b = 99999;
    long double f = a * b;
    cout<<f;

    return 0;
}

Output:

9.9999e+13

Upvotes: 1

Related Questions