In the following program I declared "long" for a, but still getting incorrect negative output after the 1860th term (all are supposed to be positive). What is the cause?

``````int main()
{
for (int i=1; i<=2000; i++)
{
long a=i*i*i/2-3*i*i/2+3*i-1;
cout << setw(3) << i << "\t" << setw(8) << a << endl;
}
}
``````
8
Contributors
12
Replies
63
Views
5 Years
Discussion Span
Last Post by asifalizaman

1860^3 = 6,434,856,000
long = 4 bytes (even unsigned < 4,294,967,296)

At iteration 1861 you surpass the max for a signed long and it starts returning negative values. Try using `ulong a=i*i*i/2-3*i*i/2+3*i-1;`.

Thanks. Is there a remedy?

Try using `ulong a=i*i*i/2-3*i*i/2+3*i-1;`.

Overflowing signed data types, while technically undefined behavior, nearly always manifests as wrapping around. So if you have the largest possible value and add 1 to it, the result will (typically) be the smallest possible value.

Thanks. I changed to "unsigned long", and it worked for 10000. However, many large numbers are not displated completely, missing the last few digits??

Edited by sgw

You can use unsigned and associate the last two terms to get half of the last multiplier. That means, `i*i*(i/2)` which is 4,000,000,000 for i = 2,000.

Edited by CGSMCMLXXV

You either need to use a large number library to handle very large numbers or if you can get away with numbers less than 18,446,744,073,709,551,615 then you can use an `unsigned long long`

You can use unsigned long long or you can create a class that can handle infinite numerical value (although may not be worth in some particular case).

Hi all, thanks again. I tried to change the type to double, and print out without decimal part, it can deal with larger numbers than unsigned long. Maybe this is the best?

I tried to change the type to double, and print out without decimal part, it can deal with larger numbers than unsigned long. Maybe this is the best?

`double` isn't magic though. A number like 100,000,000,000,000,000 (or 10^17) will not be represented exactly as a `double`. It will be represented as something like 1.0000000000000000 x 10 ^ 17. If you count, there are only 16 decimal places in that number, which means

``````1.0000000000000000 x 10 ^ 17 + 1 = 1.0000000000000000 x 10 ^ 17
``````

The precision of `double` doesn't allow you to detect a change (roughly) less that 1 part in 10^15 or 10^16 (which this change is; it's 1 part in 10^17). `unsigned long long` would be able to register this change, so that:

``````100,000,000,000,000,000 + 1 = 100,000,000,000,000,001
``````

As you noted, the restriction on the maximum value is smaller though.

It's actually a bit more complicated that this, I think, but this is the general issue. Basically, you have to decide what's more important to you: range or precision?

*******i think you check your code here
long a=iii/2-3ii/2+3*i-1;
*and change your data type long to unsigned long long then surely ..you find good result thanks*********

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.