为什么在ruby中从秒(毫秒精度)作为浮点值转换为时间会导致ruby中不一致的精度损失?
使用为什么在ruby中从秒(毫秒精度)作为浮点值转换为时间会导致ruby中不一致的精度损失?,ruby,Ruby,使用Time.at函数转换表示自历元起秒数的浮点(毫秒精度),然后提取微秒值时,结果是精度损失不一致 例如,自1970年以来每年使用1月1日: ruby-e'require(“时间”);p(1..50).map{| offset | Time.at(Time.parse({1970+offset}-01-01T00:00:0.123})到{r.分子/1000.0).usec}' [122999, 123000, 122999, 122999, 122999, 122999, 122999, 12
Time.at
函数转换表示自历元起秒数的浮点(毫秒精度),然后提取微秒值时,结果是精度损失不一致
例如,自1970年以来每年使用1月1日:
ruby-e'require(“时间”);p(1..50).map{| offset | Time.at(Time.parse({1970+offset}-01-01T00:00:0.123})到{r.分子/1000.0).usec}'
[122999, 123000, 122999, 122999, 122999, 122999, 122999, 122999, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 123000, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999, 122999]
根据-中的讨论,我预计亚秒值始终会有精度损失(即始终为122999
)。TL;博士(来自)
请注意,IEEE 754 double不够精确,无法表示自新纪元以来的精确纳秒数
关于您的期望: 我希望亚秒值始终会有精度损失(即始终为122999) 损失≠ 较少的“精度损失”并不意味着结果总是小于实际值。例如,由于精度损失,添加
0.1
和0.2
会导致值略高于0.3
:
0.1 + 0.2 #=> 0.30000000000000004
回到你的时间价值观。让我们先看看前两年,1971年和1972年:
Time.parse('1971-01-01T00:00:0.123').to_f #=> 31532400.123
Time.parse('1972-01-01T00:00:0.123').to_f #=> 63068400.123
Time.at(31532400.123).usec #=> 122999
Time.at(63068400.123).usec #=> 123000
这是因为浮点不准确。浮点数的实际值为:
31532400.1229999996721744537353515625
63068400.123000003397464752197265625
# ^^^^^^
# usec
调用nsec表明上述两项事实上都不准确:(一项略低于,另一项略高于)
要获得精确的值,必须提供精确的参数:
Time.at(31532400123.quo(1000)).usec #=> 12300
# or
Time.at(31532400, 123000).usec #=> 12300
Time.at(31532400123.quo(1000)).usec #=> 12300
# or
Time.at(31532400, 123000).usec #=> 12300