Bug #16612
closed
Enumerator::ArithmeticSequence#last with float range produces incorrect value
Added by bjfish (Brandon Fish) almost 5 years ago.
Updated over 3 years ago.
Description
Steps to reproduce
% ruby -e 'p ((0.24901079128550474)...(340.25008088980684)).step(34.00010700985213).last'
340.2500808898068
Expected result
Last value should match the value produced by the following:
ruby -e 'p ((0.24901079128550474)...(340.25008088980684)).step(34.00010700985213).to_a[-1]'
306.24997387995467
Environment
This was observed in versions 2.7.0
and 2.6.5
.
I'm unsure if the bug is in last
or in each
.
# last seems correct
[7] pry(main)> (0.24901079128550474r + 34.00010700985213r * 10).to_f
=> 340.2500808898068
[8] pry(main)> 340.25008088980684
=> 340.25008088980684
# Computing with 10 += seems correct too
[18] pry(main)> n=0.24901079128550474;
[19] pry(main)> 10.times {p n+=34.00010700985213}
34.249117801137636
68.24922481098977
102.2493318208419
136.24943883069403
170.24954584054615
204.24965285039826
238.24975986025038
272.2498668701025
306.2499738799546
340.2500808898067
=> 10
[20] pry(main)> 340.2500808898067 < 340.25008088980684
=> true
# But each/to_a gives different results:
[17] pry(main)> ((0.24901079128550474)...(340.25008088980684)).step(34.00010700985213).to_a
=> [0.24901079128550474,
34.249117801137636,
68.24922481098976,
102.24933182084189,
136.24943883069403,
170.24954584054615,
204.2496528503983,
238.24975986025044,
272.24986687010255,
306.24997387995467]
So I think last
is correct, and each
misses to yield the last element, probably due to accumulated errors.
err
in ruby_float_step_size
seems too big in this case.
- Status changed from Open to Assigned
- Assignee set to mrkn (Kenta Murata)
Since past few days/weeks, the Redmine threading is broken. Can somebody
please look into this?
Thx.
Vít
Dne 07. 02. 20 v 9:58 muraken@gmail.com napsal(a):
Issue #16612 has been updated by mrkn (Kenta Murata).
Assignee set to mrkn (Kenta Murata)
Status changed from Open to Assigned
Bug #16612: Enumerator::ArithmeticSequence#last with float range produces incorrect value
https://bugs.ruby-lang.org/issues/16612#change-84193
- Author: bjfish (Brandon Fish)
- Status: Assigned
- Priority: Normal
- Assignee: mrkn (Kenta Murata)
- ruby -v: 2.7.0
- Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
Steps to reproduce
% ruby -e 'p ((0.24901079128550474)...(340.25008088980684)).step(34.00010700985213).last'
340.2500808898068
Expected result
Last value should match the value produced by the following:
ruby -e 'p ((0.24901079128550474)...(340.25008088980684)).step(34.00010700985213).to_a[-1]'
306.24997387995467
Environment
This was observed in versions 2.7.0
and 2.6.5
.
- Status changed from Assigned to Closed
Applied in changeset git|f516379853f36d143d820c55d5eeaa9fc410ef52.
Fix Enumerator::ArithmeticSequence handling of float ranges
Depending on the float range, there could be an off-by-one error,
where the last result that should be in the range was missed. Fix
this by checking if the computed value for the expected value
outside the range is still inside the range, and if so, increment
the step size.
Fixes [Bug #16612]
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0