5

I was born in the modern world, so I don't often need to deal with this sort of thing, but could someone explain how to get the correct number in the following code. Here is one attempt of many:

#define     X   2527
#define     Y   2463
#define     Z   3072

main()
{
long int c = X*Y*Z;
printf("%ld",c);
}

I'm just trying to print a long integer but it is always printing the wrong result. Am I getting integer overflows - if so how can I prevent them? Or is it my choice of printf formatter?

cbp
  • 25,252
  • 29
  • 125
  • 205

4 Answers4

8

Overflow is ok, because you trying 34 bit number write to 32 bit variable (long int).

Use long long int and %lld in format string.

#define     X   2527LL
#define     Y   2463LL
#define     Z   3072LL

main()
{
long long int c = X*Y*Z;
printf("%lld",c);
}
Svisstack
  • 16,203
  • 6
  • 66
  • 100
  • if you use my code then not in other case for example on long ints YES. – Svisstack Nov 22 '10 at 12:52
  • 1
    @Svisstack: I think you miscounted. `2527 * 2463 * 3072` = `19120131072` decimal or `10001110011101001100000110000000000` binary, which requires 35 bits (unsigned) or 36 bits (signed), not just 34. – T.J. Crowder Nov 22 '10 at 12:53
  • 3
    Please edit 'l's to capital 'L's for those constants. Using 'l' to denote longs is imho a bad practice (obviously for the same reason we don't use 'l's for loop variables). – MaR Nov 22 '10 at 12:54
3

The problem is that the constants are not interpreted as long integers and the casting to long integer takes place only after the expression is calculated. You can cast them in the expression to solve this or simply define them as long constants. Also, long may not be enough, long long should be used instead if it is supported.

Ofir
  • 8,194
  • 2
  • 29
  • 44
  • long int have 32 bits, if you do good casts then variable will overflow too!!! This number after multiplication have 1 in 34 bit. – Svisstack Nov 22 '10 at 12:50
  • 1
    @Svisstack - not always. see http://stackoverflow.com/questions/589575/c-size-of-int-long-etc – sje397 Nov 22 '10 at 12:52
  • 1
    Yes, but in most architectures he is right. long long is guaranteed to be 64 bits if it is supported. However, it is not always supported as it is not part of ISO C89. – Ofir Nov 22 '10 at 12:54
  • 1
    @sje397: i know not always but in 98% case yes, then this is not good solution, my solution working always. – Svisstack Nov 22 '10 at 12:54
1

Yes, you are getting overflow. The answer will not fit into 32 bit signed integer, which long int is. You have to use 64 bit type, that is long long.

Also, you should do type casting, otherwise the intermediate calculation would overflow.

#define     X   2527
#define     Y   2463
#define     Z   3072

main()
{
long long c = (long long)X*Y*Z;
printf("%lld",c);
}
Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
  • 1
    I think you want to cast the #define values prior to multiplication. long long c = (long long)X * (long long)Y * (long long)Z; I'm a bit rusty with C, so take this with a grain of salt. – DwB Nov 22 '10 at 12:54
  • 1
    Casting once should do the trick. Remaining operations would automatically be performed using 64 bit calculation. – Shamim Hafiz - MSFT Nov 22 '10 at 13:01
0
#define     X   2527.0
#define     Y   2463
#define     Z   3072

main()
{
double c = X*Y*Z;
printf("%lf",c);
}

you can also use double.