有没有办法在不使用NSNumber和创建自动释放对象的情况下创建NSDecimal?

时间:2010-01-09 23:43:43

标签: ios objective-c autorelease

我正在使用NSDecimal执行大量计算,并使用以下技术创建每个NSDecimal结构:

[[NSNumber numberWithFloat:kFloatConstant] decimalValue]

我正在使用NSDecimal来避免使用自动释放的NSDecimalNumber对象(如果使用NSDecimalNumber方法进行精确计算)。但是,似乎NSNumber创建机制还会返回一个自动释放的NSNumber,从中提取小数值。

有没有办法在不使用NSNumber和创建自动释放对象的情况下创建NSDecimal

2 个答案:

答案 0 :(得分:27)

不幸的是,Apple没有提供任何简单的方法将值放入NSDecimal结构中。结构定义本身可以在NSDecimal.h头文件中找到:

typedef struct {
    signed   int _exponent:8;
    unsigned int _length:4;     // length == 0 && isNegative -> NaN
    unsigned int _isNegative:1;
    unsigned int _isCompact:1;
    unsigned int _reserved:18;
    unsigned short _mantissa[NSDecimalMaxSize];
} NSDecimal;

但我不知道我会试图逆向工程结构如何保持价值。结构中字段的下划线表示这些是私有的,可能会发生变化。我不认为在低级NSDecimal函数中会发生很多变化,但我会对某些事情在某些方面发生变化感到紧张。

鉴于此,从浮点数初始化NSDecimal最好以您描述的方式完成。但是,请注意,无论何时使用浮点值,都会丢失使用NSDecimal所获得的精度,并且会使自己遇到浮点错误。

我在高精度计算中始终只使用NSDecimals,并接收并导出NSStrings以与外界交换这些值。要基于NSString创建NSDecimal,您可以使用我们在Core Plot framework中采用的方法:

NSDecimal CPDecimalFromString(NSString *stringRepresentation)
{
    NSDecimal result;
    NSScanner *theScanner = [[NSScanner alloc] initWithString:stringRepresentation];
    [theScanner scanDecimal:&result];
    [theScanner release];

    return result;
}

在我的基准测试中,使用NSScanner而不是NSDecimalNumber -initWithString:locale:的速度提高了约90%。

答案 1 :(得分:2)

要回答“没有自动释放的对象”部分,只需:

NSDecimalNumber *intermediateNumber = [[NSDecimalNumber alloc] initWithFloat:kFloatConstant];
NSDecimal decimal = [intermediateNumber decimalValue];
[intermediateNumber release];