3

在 Flanagan 和 Matz 的The Ruby Programming Language中,我读到:

这些Numeric类在其运算符中执行简单的类型转换==,因此(例如) theFixnum 1Float 1.0compare 是相等的。

鉴于即使是两个Floats 表示1.0也可能由于舍入而无法通过相等性测试,那么如何保证 aFixnum和 a之间的相等性Float?难道不能只保证 aDecimal和 a之间Float吗?

还是这本书不准确,因为这不是本章上下文的重点?


一个编辑,希望增加清晰度:

我刚刚读到 IEEE754 (浮点)可以精确地表示最大为 2 24的整数,并且最多可以表示为 2 53的整数。根据这个问题,2 53 +1 (9,007,199,254,740,993) 是第一个不能用双精度表示的整数(因此是浮点数)。然后我的问题是,如何

9007199254­740993.0 == 90071­9925474099­3

评价为true? 舍入不应该导致左侧(不能用doubleor表示float)舍入到与右侧不匹配的值(精确整数)?

4

3 回答 3

4

正如负责该比较的函数的源代码所述(rb_integer_float_eq1.0 == 1.0

于 2013-04-07T03:52:39.390 回答
2

你确定0.9 == 0.9不能保证像这样的表达吗?我不这么认为。它在我的机器上成功了,即使存在舍入误差,算法也应该始终将相同的文字表达式映射到具有相同舍入误差的相同浮点数。例如,如果表达式"0.9"要在内部表示为0.900001,则始终如此。它有时不会映射到0.900000,有时会映射到0.900002. 所以应该保证平等。

Fixnum关于and之间的比较Float,如果将 fixnum 文字转换为浮点数,它也将映射到相同的浮点数,就好像它从一开始就是浮点数一样,具有相同的舍入误差。换句话说,以下两个进程以相同的浮点数结束:

  • 字面量"1.0"→ 一些带有舍入误差的内部浮点数(例如0.999999
  • Literal "1"→ Internal fixnum 1→ 一些带有舍入误差的内部浮点数 ( 0.999999)

编辑或者,正如 fmendez 所说,如果整数在内部精确映射到浮点数,则与整数完全对应的浮点数(如"1.0""2.0"等)在内部浮点表达式中没有任何舍入误差。所以无论如何都会保证平等。

于 2013-04-07T03:55:05.677 回答
0

在 Squeak/Pharo Smalltalk 中,我更改了等式/不等式比较测试以始终将不精确的算术值(浮点)提升为精确的算术值(整数分数 ScaledDecimal)。
http://bugs.squeak.org/view.php?id=3374

早在那之前,这是在各种 lisp 风格中完成的。
http://www.lispworks.com/documentation/lcl50/aug/aug-170.html

如果你不这样做,你会降低相等测试的一些属性,因为 2^54+1 和 2^54-1 可能都等于相同的 float double(2^54)... 与不平等。您还会遇到字典(散列图)和数字集的各种麻烦。

于 2013-04-07T08:26:23.137 回答