4

in Objective-C:

unsigned long t1 = 1310789847 * 1000;

causes an overflow and shows an incorrect result.

how do i get 1310789847000?

PengOne
  • 48,188
  • 17
  • 130
  • 149
phil b
  • 41
  • 2

2 Answers2

5

The result does not fit in a 32 bit unsigned long, so you get an overflow and the result only has the "bottom" 32 bits. You could use unsigned long long instead, which is 64 bit (on the Intel Mac, not sure about other platforms).

unsigned long long t1 = (unsigned long long)1310789847 * 1000;

64 bit integer literals are designated by L, so you could also do:

unsigned long long t1 = 1310789847L * 1000;

Since you are dealing with literals, the above is true. I just found out that for variables, there is no need to cast (Xcode 4):

unsigned long a = 1310789847;
unsigned long b = 1000;
unsigned long long t1 = (unsigned long long)a * b; 
unsigned long long t2 = a * (unsigned long long)b;
unsigned long long t3 = a * b;
unsigned long long t4 = 1310789847 * 1000;
NSLog(@"%lld %lld %lld %lld\n", t1, t2, t3, t4);

The output is:

2011-07-16 08:33:40.445 LongLongTest[16738:903] 1310789847000 1310789847000 1310789847000 824821720

FWIW, I am surprised the compiler notices that the operands must be expanded to 64 bit before doing the multiplication, but can't do the same for literals.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
5

Use NSDecimal. There are all sorts of handy functions in the Foundation framework for manipulating NSDecimal structs, which are basically super large numbers (not just integers). You get the basic operations of add, subtract, multiply, divide, exponentiate, etc, but those are usually powerful enough to do quite a bit of stuff.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • A bit overkill, but this is the right idea if phil was working with very large numbers. – Mike Bailey Jul 16 '11 at 06:44
  • @Mike yeah, if you need something beyond the range of an `unsigned long long`, `NSDecimal`'s the way to go. – Dave DeLong Jul 16 '11 at 06:45
  • I would still recommend Rudy's answer over this, unless phil is actually dealing with numbers so large they're overflowing even unsigned long longs. But, at that point I'd seriously reconsider possibly rescaling my data or figuring out why I'm getting overflows. Outside of high precision computations, I'd be very concerned if those unsigned long longs weren't enough. – Mike Bailey Jul 16 '11 at 06:48
  • Of course, I was just using integers as a base case of sorts. I just mean to say in most applications you'll want to use what's natively supported (ints, floats, doubles, etc) if it's possible. – Mike Bailey Jul 16 '11 at 06:54
  • @Mike agreed. Use the primitives when you can, because those will *always* be faster. – Dave DeLong Jul 16 '11 at 21:38