为什么第二次比较中的false
?我没有加载任何库。
puts RUBY_DESCRIPTION
t = Time.now
t1 = Time.at(t.to_f)
t2 = Time.at(t.to_f)
puts( t1 == t2 )
puts( t == t1 )
puts( t.to_f == t1.to_f )
printf "%.64f\n%.64f\n%.64f\n", t, t1, t2
输出:
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
true
false
true
1347661545.4348440170288085937500000000000000000000000000000000000000000000
1347661545.4348440170288085937500000000000000000000000000000000000000000000
1347661545.4348440170288085937500000000000000000000000000000000000000000000
我在1.8.7上获得所有true
。发生了什么事?
据我所知,我更新了脚本以显示浮动是相同的。我错过了什么吗?
答案 0 :(得分:4)
来自Time.to_f上的文档:“请注意,IEEE 754 double不足以表示Epoch的纳秒数。”为了说明@ oldrinb的评论:
puts RUBY_DESCRIPTION # ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]
t = Time.now
p t.subsec #=> (40189433/100000000); # a Rational, note the last digits 33
p t.to_f #=> 1347661635.4018943 # last digit missing 3
Time#subsec documentation:“#to_f和subsec的最低位不同,因为IEEE 754 double不足以表示理性。准确的值由subsec返回。”
答案 1 :(得分:1)
我愿意打赌这是一个经典的浮点精度问题。具体来说,当您调用#to_f
时,您可能会丢失原始对象中的精确度。
如果您比较每个对象的#nsec
值,则可以轻松地看到这一点:
1.9.3p194 :059 > t = Time.now
=> 2012-09-14 15:29:59 -0700
1.9.3p194 :060 > t2 = Time.at(t.to_f)
=> 2012-09-14 15:29:59 -0700
1.9.3p194 :062 > t.nsec
=> 489932427
1.9.3p194 :063 > t2.nsec
=> 489932537
Time.at(t.to_f) == Time.at(t.to_f)
可能成功的原因是两者在输入中都有相同的浮点精度损失,因此它们的输入确实相同。
所以,总而言之,这是一个错误的行为,但它不是一个错误/本身/,因为它与浮点运算的基本警告有关。