Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 将十进制转换为双精度的不一致性(目标C)_Objective C_Nsdecimalnumber - Fatal编程技术网

Objective c 将十进制转换为双精度的不一致性(目标C)

Objective c 将十进制转换为双精度的不一致性(目标C),objective-c,nsdecimalnumber,Objective C,Nsdecimalnumber,代码9.4.1。在调试器控制台中,我看到的结果对我来说很奇怪: (lldb) print (double)0.07 (double) $0 = 0.070000000000000007 (lldb) print [(NSDecimalNumber*)[NSDecimalNumber decimalNumberWithString:@"0.07"] doubleValue] (double) $1 = 0.069999999999999993 如果在编译代码中执行,我会看到相同的结果。我不明白为

代码9.4.1。在调试器控制台中,我看到的结果对我来说很奇怪:

(lldb) print (double)0.07
(double) $0 = 0.070000000000000007
(lldb) print [(NSDecimalNumber*)[NSDecimalNumber decimalNumberWithString:@"0.07"] doubleValue]
(double) $1 = 0.069999999999999993
如果在编译代码中执行,我会看到相同的结果。我不明白为什么将文字0.07转换为双精度时,以及将十进制0.07转换为双精度时,结果会有所不同。为什么精度会以不同的方式丢失


我遗漏了什么?

NSDecimalNumber
的设计与您看到的完全一样。它使用“以10为基数的数学”来避免您所看到的问题——数字的传统浮点表示法无法准确表示我们习惯于编写的以10为基数的数字

指导你“去研究数值方法”的评论有点鲁莽,但它的方向是正确的。更好地利用您的时间是(同时)查看
NSDecimalNumber
的文档,并思考它的作用以及它存在的原因


几分钟前,我从未听说过
NSDecimalNumber
,因此感谢您为我介绍一些新知识。:-)

计算值的方式不同

(lldb) p 7.0 / 100.0
(double) $0 = 0.070000000000000007
(lldb) p 7.0 / 10.0 / 10.0
(double) $1 = 0.069999999999999993

纸上的精度是无限的,但在计算机计算中,它的精度是有限的。去研究数值方法。你们只需要从不同的来源得到两个值,它们自己解释0.7的数字。第一种情况是LLVM,第二种情况是NSDecimalNumber的实现。这就是全部。我想这没什么大不了的。你为什么要用
NSDecimalNumber
,为什么要把
NSDecimalNumber
转换成double?可能我还不够清楚。问题是,为什么在一种情况下我看到0.070000000007的值,而在另一种情况下,该值是0.069999999993。它们都由相同的十进制值生成。似乎编译器和NSDecimalNumber类的转换方式不同。不同的舍入概率在从10进制表示到2进制表示的转换过程中,有时可能会有足够的剩余浮点精度损失,从而导致以这种方式表示的差异。这帮不了什么忙,而且会导致意想不到的字符串表示差异,正如您所清楚看到的那样。您收到的评论和回答直接针对您的问题。将0.7转换为二进制以将其存储为double(或将其转换为double)时,结果是0.000100011101加上大量二进制数字。如果你从这个值转换回基数10,你就得不到精确的.07。得到1/16+1/256+1/512+1/1024+1/2048,约为0.06982421875。当你将二进制分数扩展到更多的数字时,它将接近.07,但我认为它永远不会到达那里……另一方面,如果你将.07放入一个
NSDecimalNumber
(它是为了解决你所观察到的问题而创建的)它不是存储为二进制分数,而是存储为一个大整数,包含所有有效数字(在本例中,仅为7)和指数(在本例中为-2)。因为我们存储的是7而不是.07,所以精度不会降低,因为7可以很容易地用二进制(111)表示。“转换以不同方式进行”是正确的。我们一直试图解释的是,如何/为什么采取不同的做法。:-)你有任何关于这一点的参考资料吗?为什么他们是这样计算的?我没有任何参考资料,这是一个有根据的猜测。编译器正在分析字符串,而
NSDecimalNumber
正在转换十进制数。试试
po[NSNumber numberWithDouble:0.07]
,效果类似。
NSDecimalNumber
也会得到一个字符串作为输入。编译器将字符串直接转换为double,而
NSDecimalNumber
首先将其转换为十进制格式。但字符串表示和十进制格式之间不应存在任何精度损失。所以,我只是好奇为什么结果不同。