What is most common and correct practice to get a CGFloat from an NSNumber?
This will get the correct result in any case:
NSNumber *n = @42.42;
CGFloat cgf = [n doubleValue];
because CGFloat
is either float
or double
.
NSNumber
does not have a CGFloatValue
method. You could define one
using the toll-free bridge to CFNumberRef
:
@interface NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue;
@end
@implementation NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue{
CGFloat result;
CFNumberGetValue((__bridge CFNumberRef)(self), kCFNumberCGFloatType, &result);
return result;
}
@end
or using the C11 feature "Generic selection", where the compiler chooses the appropriate
code depending on the type of CGFloat
:
@implementation NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue{
CGFloat result;
result = _Generic(result,
double: [self doubleValue],
float: [self floatValue]);
return result;
}
@end
And then
NSNumber *n = @42.24;
CGFloat f = [n myCGFloatValue];
but I doubt that it is worth the hassle.
Just always get the double value. If CGFloat is only a ‘float’ on your machine the double will be instantly truncated, so you don’t care.
The older answers are both correct. Just for my 2¢, here's my implementation:
@implementation NSNumber (TypeConversion)
- (CGFloat)cgFloatValue
{
#if CGFLOAT_IS_DOUBLE
return self.doubleValue;
#else
return self.floatValue;
#endif
}
@end
This relies on the definition of CGFLOAT_IS_DOUBLE
in CGBase.h for Objective C, or CoreGraphics.h for Swift:
// Don't write this code; it's already included in Foundation :)
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif
typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1
From CoreGraphics.h