首先,取一个特定的浮点数f
:
f = [64.4, 73.60, 77.90, 87.40, 95.40].sample # take any one of these special Floats
f.to_d.class == (1.to_d * f).class # => true (BigDecimal)
因此,使用 BigDecimal
进行乘法运算会将 f
转换为 BigDecimal
。 因此,1.to_d * f
(或 f * 1.to_d
)可以看作是将 f
转换为 BigDecimal
的一种(低效但仍然有效的)形式。 然而对于这些特定值,我们有:
f.to_d == 1.to_d * f # => false (?!)
这难道不是一个bug吗?我本以为在用1.to_d
乘以一个数时,Ruby会在内部调用f.to_d
。但结果不同,例如对于 f = 64.4
:
f.to_d # => #<BigDecimal:7f8202038280,'0.644E2',18(36)>
1.to_d * f # => #<BigDecimal:7f82019c1208,'0.6440000000 000001E2',27(45)>
我不明白为什么浮点数表示错误应该成为这里的借口,但它显然是一个原因,那么为什么会发生呢?
PS.我写了一段代码来解决这个问题:https://github.com/Swarzkopf314/ruby_wtf/blob/master/multiplication_by_unit.rb
f == f.to_d
是否返回 true? - Eli Sadoff.to_d
后,f
取什么值?内部表示通常是非常明显的。 - tadman