CoreData provides Integer 16, Integer 32 and Integer 64 storage, but doesn't support any sign qualifiers. You can store an unsigned int (32 bit) as a signed long (64 bit) and make sure the value is preserved for the full range, but an unsigned long seems to require a 128 bit signed integer to store, which of course isn't supported by CoreData. Is there any way then to store unsigned long in coreData?
4 Answers
[Previous comment promoted to answer]
Sounds like it is the bit pattern which is important to you and not the integer value per se. You can store it as a signed - just cast it as C signed<->unsigned casts don't enforce mathematical correctness and just preserve the bits. Cast it back to use it.
Follow up question:
In general yes in (Obj-)C(++) you can store an unsigned integer value into a variable with the equivalent signed integer type, and vice-versa. C casts from signed -> unsigned by definition equate to a bit-copy when using 2's complement integers and the two types are the same size. Going the other way, unsigned -> signed, is "implementation defined" - which in practice usually means a bit-copy. Clang & GCC use a bit-copy for both, but if you want to be absolutely certain you can use a union
:
unsigned long r;
long l;
r = (unsigned long)l; // will always work (cast optional)
// following is l = (long)r (cast optional) without "implementation defined" risk
{ union { long sValue; unsigned long uValue; } tmp; tmp.uValue = r; l = tmp.sValue;}
But seriously I doubt anybody would! (Note: Clang at least will compile it down to a straight assignment (bit-copy).)

- 52,522
- 5
- 70
- 86
If you really need the full precision of 64 bit unsigned, you can make it transformable (check the documentation about storing Non-Standard Persistent Attributes). CoreData let's you store just about anything that way. But you probably don't need the full 64-bit precision...?!?

- 6,665
- 2
- 25
- 41
-
I'm trying to store a file number, which is given to me as an unsigned long, and I'm not sure what guarantee the os makes about the range of inode numbers. – Tony Jan 19 '12 at 22:12
-
3@Tony - sounds like it is the bit pattern which is important to you and not the integer value per se. You can store it as a signed - just cast it as C signed<->unsigned casts don't enforce mathematical correctness and just preserve the bits. Cast it back to use it. – CRD Jan 19 '12 at 23:44
-
I see, that's very helpful. I'd mark it as the right answer if it wasn't a comment. Now, does that mean that in general if you have an unsigned value you can still store it inside a signed value even if it overflows so long as you guarantee to cast it back later? – Tony Jan 20 '12 at 00:01
An unsigned long
is not 128bits (yet).
(or do you have a 128bits CPU?)
On a Mac, depending on your CPU architecture, it may be 32 or 64 bits.
See with:
NSLog( @"%u", sizeof( unsigned long ) );
So basically an unsigned long
will be compatible will Integer32
or Integer64
.

- 52,708
- 13
- 106
- 123
-
Slight misread of the question here, the OP didn't say unsigned long is 128 bits but that you appear need a 128-bit signed value to store all the values expressible as unsigned long - technically you only need a 65-bit signed but for some reason they are not common ;-). `NSNumber` stores an unsigned long as a signed 128-bit value (as internally it stores all integers as signed). – CRD Jan 19 '12 at 18:14
You could always convert [de]serialize it as a string. It isn't particularly clean, but it gives you the ability to store it as long as you can parse it back into an unsigned long.

- 30,869
- 25
- 117
- 173
-
1
-
Like I said, it isn't clean, but it would _work_, even though there are probably _many_ better ways. In general, strings are a functional "lowest common denominator" and many people forget that they are the entire foundation of UNIX inter-process communication. – cdeszaq Jan 19 '12 at 17:49
-
-
People will always complain though if they don't know what they are doing. And having a working starting point is easier to optimize than a non-working one. – cdeszaq Jan 19 '12 at 17:58