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;
   }
}

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??

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.

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*********

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.