使用NSNumber和创建自动释放的对象的情况下创建NSDeci

使用NSNumber和创建自动释放的对象的情况下创建NSDeci

本文介绍了有没有办法在不使用NSNumber和创建自动释放的对象的情况下创建NSDecimal?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  [[NSNumber numberWithFloat:kFloatConstant] decimalValue] 

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



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

解决方案

不幸的是,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所获得的精度,并且会使自己遇到浮点错误。



Core Plot框架中采用的方法:

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

返回结果;
}

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


I am carrying out a number of calculations using NSDecimal and am creating each NSDecimal struct using the following technique:

[[NSNumber numberWithFloat:kFloatConstant] decimalValue]

I am using NSDecimal to avoid using autoreleased NSDecimalNumber objects (if the NSDecimalNumber approach to accurate calculations is used). However it seems that the NSNumber creation mechanism also returns an autoreleased NSNumber from which the decimal value is extracted.

Is there a way to create an NSDecimal without using NSNumber and creating autoreleased objects?

解决方案

Unfortunately, Apple does not provide any easy ways of putting values into an NSDecimal struct. The struct definition itself can be found in the NSDecimal.h header:

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;

but I don't know that I would go around trying to reverse-engineer how the structs hold values. The underscores on the fields in the struct indicate that these are private and subject to change. I don't imagine that a lot of changes occur in the low-level NSDecimal functions, but I'd be nervous about things breaking at some point.

Given that, initializing an NSDecimal from a floating point number is best done in the way that you describe. However, be aware that any time you use a floating point value you are losing the precision you've gained by using an NSDecimal, and will be subjecting yourself to floating point errors.

I always work only with NSDecimals within my high-precision calculations, and take in and export NSStrings for exchanging these values with the outside world. To create an NSDecimal based on an NSString, you can use the approach we take in the Core Plot framework:

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

    return result;
}

Using an NSScanner instead of NSDecimalNumber -initWithString:locale: is about 90% faster in my benchmarks.

这篇关于有没有办法在不使用NSNumber和创建自动释放的对象的情况下创建NSDecimal?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 21:09