Project

General

Profile

Actions

Bug #16612

closed

Enumerator::ArithmeticSequence#last with float range produces incorrect value

Added by bjfish (Brandon Fish) about 4 years ago. Updated almost 3 years ago.

Status:
Closed
Target version:
-
[ruby-core:97075]

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.

Updated by Eregon (Benoit Daloze) about 4 years ago

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.

Updated by nobu (Nobuyoshi Nakada) about 4 years ago

err in ruby_float_step_size seems too big in this case.

Updated by mrkn (Kenta Murata) about 4 years ago

  • Status changed from Open to Assigned
  • Assignee set to mrkn (Kenta Murata)

Updated by Anonymous about 4 years ago

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 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.

Updated by jeremyevans0 (Jeremy Evans) almost 3 years ago

I've traced this to an off-by-one in ruby_float_step_size. I've submitted a pull request to fix this: https://github.com/ruby/ruby/pull/4434

@Eregon (Benoit Daloze) Unfortunately, you can't get #each to work like repeated edition without breaking backwards compatibility. It can change terminating loops into infinite loops in pathologic cases, and such pathological cases are part of the test suite. I tried that approach first (https://github.com/jeremyevans/ruby/commit/962edf65affe8ab1fc18b9a46317c543ef31bec8).

Actions #6

Updated by jeremyevans (Jeremy Evans) almost 3 years ago

  • 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]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0