Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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
Ruby'中的浮点错误;什么是大十进制类?_Ruby_Bigdecimal_Floating Accuracy - Fatal编程技术网

Ruby'中的浮点错误;什么是大十进制类?

Ruby'中的浮点错误;什么是大十进制类?,ruby,bigdecimal,floating-accuracy,Ruby,Bigdecimal,Floating Accuracy,在ruby中避免浮点错误的通用建议是使用BigDecimal。我一定忽略了什么,因为我想我发现了一个例子,BigDecimal math返回一个错误,而Float没有: 使用Float给出2.75的正确答案: > 50.0 * 0.6 / 360.0 * 33 => 2.75 使用BigDecimal给出了2.7499999的错误答案: > BigDecimal("50") * BigDecimal("0.6") / BigDecimal("360") * BigDecima

在ruby中避免浮点错误的通用建议是使用BigDecimal。我一定忽略了什么,因为我想我发现了一个例子,BigDecimal math返回一个错误,而Float没有:

使用Float给出2.75的正确答案:

> 50.0 * 0.6 / 360.0 * 33
=> 2.75
使用BigDecimal给出了2.7499999的错误答案:

> BigDecimal("50") * BigDecimal("0.6") / BigDecimal("360") * BigDecimal("33")
=> #<BigDecimal:7efe74824c80,'0.2749999999 999999989E1',27(36)>
>BigDecimal(“50”)*BigDecimal(“0.6”)/BigDecimal(“360”)*BigDecimal(“33”)
=> #

有人请告诉我这里缺少什么?

让我们简化您的示例,改用这个:

BigDecimal(1) / BigDecimal(3) * BigDecimal(3)
# => #<BigDecimal:19289d8,'0.9999999999 99999999E0',18(36)>

你的问题是为什么BigDecimal会给出错误,或者为什么Float不会给出错误?为什么BigDecimal会给出错误?这个例子是否意味着我们不能再信任BigDecimal进行浮点计算?请参阅。您误解了浮点math.FWIW,如果可以的话,请在除法之前先乘法:
BigDecimal(“50”)*BigDecimal(“0.6”)*BigDecimal(“33”)/BigDecimal(“360”)
,然后得到所需的结果。@Mladen的答案已经告诉你,如果你按自己的方式做,为什么不能得到准确的结果。如果你第一次乘法,得到精确结果的几率更高。上面的行不产生任何重复的小数。
990/360
(或
(11*90)/(4*90)
),这不会产生任何重复的小数。从2.1开始,可以使用
r
后缀:
50r*Rational(0.6)/360r*33r
。谢谢你。我正在编写一个金融应用程序,并考虑了以下所有表示货币的类型:*整数,以美分存储金额:不好,因为我们需要能够存储美分的分数。*金钱宝石:使用整数,所以问题与整数相同。*浮点:容易出现浮点错误。*BigDecimal:不太容易出现浮点错误(但现在我发现,在我们的一个用例中,仍然容易出现错误!)也许Rational就是答案……另一个似乎对我有效的解决方案:BigDecimal(“50”)*BigDecimal(“0.6”)*BigDecimal(“33”)/BigDecimal(“360”)这是基于Jordan将其标记为重复的线程中的一条评论:实际上,准确进行此类计算的关键不是使用定点算法,而是安排计算以避免将要放大的值舍入。例如,要向某人收取30天每月17天的费用,请将每月金额乘以17再除以30,而不是除以30再乘以172014年10月1日15:13举行超级杯
BigDecimal(1) / BigDecimal(3)
# => #<BigDecimal:1921a70,'0.3333333333 33333333E0',18(36)>
(Rational(50) * Rational(0.6) / Rational(360) * Rational(33)).to_f
# => 2.75