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

Uri*_*zen 17 objective-c autorelease ios

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

[[NSNumber numberWithFloat:kFloatConstant] decimalValue]
Run Code Online (Sandbox Code Playgroud)

NSDecimal用来避免使用自动释放的NSDecimalNumber对象(如果使用NSDecimalNumber精确计算的方法).但是,似乎NSNumber创建机制还返回一个自动释放NSNumber的十进制值.

有没有办法创建一个NSDecimal不使用NSNumber和创建自动释放的对象?

Bra*_*son 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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

    return result;
}
Run Code Online (Sandbox Code Playgroud)

使用NSScanner而不是NSDecimalNumber -initWithString:locale:在我的基准测试中快了大约90%.

  • @AndrewS - 例如,NSDecimal不是一个类,而是一个结构体,因此需要处理的方式与标准对象略有不同.NSDecimal处理函数的复杂性似乎源于希望尽可能快地实现它们.请注意,它们通过引用传递给这些函数,仅作为一个优化.但是,没有理由不为NSDecimals提供简单的构造函数. (3认同)
  • @AndrewS - 不会.像`float`和`double`这样的浮点标量不会以这样的格式存储它们的值来执行像NSDecimal这样的base-10算术. (2认同)