5

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?

Tony
  • 30,345
  • 9
  • 45
  • 77

4 Answers4

4

[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).)

CRD
  • 50,500
  • 4
  • 64
  • 80
2

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...?!?

Daniel Eggert
  • 6,547
  • 2
  • 23
  • 40
  • 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 signedunsigned 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
1

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.

Macmade
  • 49,018
  • 12
  • 104
  • 121
  • 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
0

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.

cdeszaq
  • 29,170
  • 25
  • 111
  • 169
  • 1
    Don't convert to string. That's very expensive. – Daniel Eggert Jan 19 '12 at 17:44
  • 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
  • And then people start complaining about CoreData is slow. – Daniel Eggert Jan 19 '12 at 17:56
  • 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