Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encoding/decoding CGFloat on 32- vs 64-bit

I'm converting an app to work in 64-bit. The Apple docs state that the CGFloat type is a float on 32-bit and a double on 64-bit.

If that is so, how do you handle encoding/decoding of the value? For instance, if creating an NSNumber from a CGFloat, should I use the -numberWithFloat: or -numberWithDouble: method of NSNumber? The same question applies to the NSCoder and NSKeyedArchiver methods -encodeFloat:forKey: and -encodeDouble:forKey:.

Do I have to write a conditional macro so that -numberWithFloat: is called on 32-bit and -numberWithDouble: on 64-bit?

What happens if a user running the 64-bit version of the app saves a file where these values are encoded as doubles and the file is opened/unarchived on a 32-bit system?

All the methods in my app that use CGFloats are unlikely to ever need the precision level of a double, so should I even be worrying about this?

like image 498
Rob Keniger Avatar asked Nov 17 '09 03:11

Rob Keniger


1 Answers

What happens if a user running the 64-bit version of the app saves a file where these values are encoded as doubles and the file is opened/unarchived on a 32-bit system?

Nothing special. The file contains a double, and presumably you're sending decodeDouble:forKey: to retrieve the value, so you'll get a double. You can then cast it to CGFloat—which will lose precision if you're on a 32-bit machine, but you have to do that cast sooner or later. (Even if you hold onto the double, you'll still have to cast to CGFloat when you pass the value to Quartz/AppKit/UIKit.)

Consider the alternative: You store floats in the file on a 64-bit machine, and then load the file back in on the same machine. You and Quartz can handle the full precision of the 64-bit double type, but you don't have it, because you threw it away when you wrote out the file. If the value changed at all in the cast, that change is now permanent.

So my recommendation is to always use the double type with NSKeyedArchiver, unless you know that you are never going to use anything but float (i.e., the target API only uses float, never double). This isn't true of Quartz, so for CGFloat, use double.

like image 185
Peter Hosey Avatar answered Oct 19 '22 17:10

Peter Hosey