NSNumber计算和精度?

fuz*_*oat 3 cocoa objective-c

如果可能的话,有两个快速的问题,这就是我应该如何处理两个NSNumber对象,进行计算并最终得到一个同样是NSNumber的结果?

NSNumber *flux = [[NSNumber alloc] initWithDouble:100.0];
NSNumber *mass = [[NSNumber alloc] initWithDouble:3];

double intermediate = [flux doubleValue] / [mass doubleValue];
NSLog(@"INTER : %.20f", intermediate);

NSNumber *result = [[NSNumber alloc] initWithDouble:intermediate];
NSLog(@"RESULT: %@", result);

...
...

[flux release];
[mass release];
[result release];
Run Code Online (Sandbox Code Playgroud)

另外从NSLog查看控制台的结果,是否有任何精度损失?我会假设没有,我看到的只是显示精度,但只是好奇吗?

INTER : 33.33333333333333570181
RESULT: 33.33333333333334
Run Code Online (Sandbox Code Playgroud)

加里

Tec*_*Zen 14

(与您的问题相关但相关)

NSNumber不打算用10进行数学运算.它主要用于包装和存储数值.如果你需要做真正的数学运算,你想要使用NSDecimal.

NSDecimalNumber是NSNumber的不可变子类,它提供了一个面向对象的包装器,用于执行base-10算术.实例可以表示任何可以表示为尾数x 10 ^指数的数字,其中尾数是长度为38位的十进制整数,指数是-128到127之间的整数

尽管我们称它们为"计算机",但我们的逻辑引擎无法进行实际数学计算,因此必须对其进行伪造.当你达到非常大或非常小的数字的极端时,这种假装开始显现.这就是为什么你需要自定义数字类,它可以容纳更多的信息,而不仅仅是一串数字.

因此,如果您对精度有任何疑虑,请使用NSDecimal而不是NSNumber.NSDecimal旨在执行精确计算.

Edit01:

...我应该如何处理两个NSNumber对象,执行计算并最终得到一个同样是NSNumber的结果?

严格来说,您不应该使用NSNumber进行计算.您会注意到NSNumber没有专门的数学方法.您必须转换为标量然后再返回到对象.这会导致精度损失,并且精度可能会根据硬件或标量的定义而改变.

相反,NSDecimal可以精确地表示非常精确的数字,因为它抽象地保留它们.它具有执行精确数学运算的专用方法.

另外从NSLog查看控制台的结果,是否有任何精度损失?

是的,除了格式化之外,还有数学精度的损失.标量具有不同的精度,具体取决于它们的类型和存储数量的大小.在较大的范围内,这会导致精度问题.如果混合类型,比如NSInteger和NSUInteger,则可以获得NSInteger的最大精度.

您还遇到了使用标量的所有旧问题.

如果使用无法保存该值的类型向NSNumber对象请求其值,则会返回错误结果 - 例如,如果要求使用大于FLT_MAX的double创建的数字的浮点值,或者使用大于NSInteger的最大值的float创建的数字的整数值.

NSDecimal使您摆脱所有这些可能的错误来源.它可以进行精确的数学计算,其大小超出任何人在现实世界中的使用范围.

我再说一遍:如果需要精确度,请不要使用NSNumber或标量.