8

What's the largest value an NSNumber can store?

// ok
    NSNumber *value = @(1 << 31); 

// gives compiler error, so max NSNumber is 32-bit uint?
    NSNumber *value = @(1 << 32); 
jtbandes
  • 115,675
  • 35
  • 233
  • 266
Boon
  • 40,656
  • 60
  • 209
  • 315
  • 6
    The answers already answer the actual question, so I'll explain the error. The `1` in `1 << 32` is an int, and the compiler uses that when it performs the shift. Since an int is 32 bits, you cannot shift it 32 positions. If you used `@(1ULL << 32)`, it would work, because `1ULL` has a type of unsigned long long. – ughoavgfhw Feb 21 '13 at 05:41
  • 1
    Why would this question be voted down? Down vote trolling? – Boon Feb 22 '13 at 14:46

1 Answers1

8

NSNumber is actually a class cluster, meaning that when you create an instance you may be getting any of a variety of concrete subclasses, each capable of storing a different kind of numeric type. The actual types available, and their sizes, may be machine-dependent.

Looking at the NSNumber documentation shows you the different kinds of numbers you can store: the two largest integer options would be +numberWithLongLong: (or +numberWithUnsignedLongLong:), which stores a long long, and +numberWithInteger: (or +numberWithUnsignedInteger:), which stores an NSInteger. The maximum NSNumber values are therefore limited by these types.

The Foundation documentation states:

When building 32-bit applications, NSInteger is a 32-bit integer. A 64-bit application treats NSInteger as a 64-bit integer.

The compiler is smart and will create an NSNumber of the same type as your numeric literal. As mentioned in the comments above, you can use @(1ULL << 32) if your machine has an unsigned long long type with more than 32 bits.

Furthermore, NSNumber is toll-free bridged to CFNumber, meaning you can try out functions like CFNumberGetByteSize() for yourself — and have a look at the Number Types section of the CFNumber documentation. You'll see these are basically the same as the NSNumber options.

Additionally, the NSDecimalNumber class, a subclass of NSNumber, provides the +maximumDecimalNumber method which you can use to find the maximum value that can be stored in an NSDecimalNumber. NSDecimalNumber, and the floating-point types, may be able to store bigger numbers than the integer types, though with decreasing precision.

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • What about `NSNumber *value = @(pow(2, 128));`? – Sebastian Feb 21 '13 at 05:36
  • 1
    @Sebastian Since `pow` returns a `double`, the compiler will use `+numberWithDouble:` (or something equivalent to this). – jtbandes Feb 21 '13 at 05:38
  • 3
    The largest integer that you could store then, would be using an unsigned long long, which is 64 bit. (18,446,744,073,709,551,615). NSDecimalNumber is technically a different class, and therefore has a different max number. – lnafziger Feb 21 '13 at 05:47
  • Thanks, all. I updated my answer to address the maximum values of different types. – jtbandes Feb 21 '13 at 05:48
  • @lnafziger Your comment should be the accepted answer. –  May 26 '17 at 02:20