Reputation: 33
When I attempt to create an NSNumber using the numberWithLongLong with a number greater than -2 and less than 13 it returns a number that is casted as an (int).
I see this if I look at the Xcode debugger after stepping over my line.
NSNumber* numberA = [NSNumber numberWithLongLong:-2]; //Debugger shows as (long)-2
NSNumber* numberB = [NSNumber numberWithLongLong:-1]; //Debugger shows as (int)-1
NSNumber* numberC = [NSNumber numberWithLongLong:12]; //Debugger shows as (int)12
NSNumber* numberD = [NSNumber numberWithLongLong:13]; //Debugger shows as (long)13
To put my problem in context, I am using a long long value for an epoch date that I will end up serializing using BSON and sending across the wire to a webservice. The webservice requires the date to be a java Long.
Thanks in advance
Upvotes: 3
Views: 1911
Reputation: 42588
Wait. I think I know what your asking. Try it this way:
NSNumber* numberA = [NSNumber numberWithLongLong:-2LL];
NSNumber* numberB = [NSNumber numberWithLongLong:-1LL];
NSNumber* numberC = [NSNumber numberWithLongLong:12LL];
NSNumber* numberD = [NSNumber numberWithLongLong:13LL];
BTW: it won't matter what the type of the constant is, it will be coerced into a long long
when passed to [NSNumber numberWithLongLong:]
UPDATE
Based on @robmayoff's answer, I don't think NSNumber is reliable for your. How are you packing your BSON? is there a way to use NSValue instead of NSNumber?
Upvotes: 1
Reputation: 385540
You have discovered that NSNumber (actually, its CFNumber counterpart) has a cache for integers between -1 and 12 inclusive. Take a look at the CFNumberCreate
function in CFNumber.c
to see how it works.
It looks like you can force it not to use the cache by passing your own allocator to CFNumberCreate
. You'll need to look at the CFAllocator
documentation.
But note that the CFNumberCreate
manual says this:
The
theType
parameter is not necessarily preserved when creating a newCFNumber
object.
So even if you bypass the cache, you might not get back an object whose objCType
is q
(which means long long
). It looks like the current implementation will return q
but that could change in a future version.
You are allowed to write your own NSNumber
subclass if you need to guarantee that objCType
returns q
. Read “Subclassing Notes” in the NSNumber Class Reference.
Upvotes: 6
Reputation: 53000
You can use your webservice without concern.
NSNumber
wraps a numeric value (of primitive type) as an object. How NSNumber
stores that value is not really your concern (but there is a method to find it out), it is an opaque type. However NSNumber
does maintain an internal record of the type used to create it so its compare:
method can follow C rules for comparison between values of different types precisely.
For integral types the integral value you get back will be exactly the same, in the mathematical sense, as the one you created the NSNumber
with. You can create an NSNumber
with a short
and read its value back as a long long
, and the mathematical value will be the same even though the representation is different.
So you can store your integral date value as an NSNumber
and when you read it back as a long long
you will get the right value. No need to be concerned how NSNumber
represents it internally, and indeed that could potentially change in the future.
(At least one implementation of NSNumber
can store values as 128-bit integers, which helps ensure correct semantics for signed and unsigned integers. Also I stressed integral types as with the vagaries of real numbers talking about mathematical exactness is somewhat moot.)
Upvotes: 3