From: Shyouhei Urabe Date: 2011-09-13T21:19:51+09:00 Subject: [ruby-core:39518] [Ruby 1.9 - Bug #4576] Range#step miss the last value, if end-exclusive and has float number Issue #4576 has been updated by Shyouhei Urabe. Vit Ondruch wrote: > Shyouhei Urabe wrote: > > Vit Ondruch wrote: > > > Please first see the commit [1] and then tell me why the original test case should fail? > > > > Because no one guarantees that it should pass. > > It is a feature I guess, there is even test case for this unfortunately, so why should something pass on one platform and should not pass on another? That doesn't make sense. It is a hardware issue. So it is quite natural for one platform behaves differently than another. > > > Actually it fails on i386 and succeeds on x86_64 which is a bit suspicious. > > > > It is a clear sign that you are "dancing with floats". > > > > As Tomoyoki Chikanaga says in note #note-2 of this issue I believe this is a "learn floating point number" kind of thig. > > No, it is not ... the main difference is if the float comparison is done in memory or in registers. Each have different precision and it popups on i386. Yes, I know. And you cannot force your C compiler to use specific hardware (except by compiler flags). Your patch is insufficient for your needs. In fact, C lacks a way to specify how a floating number should be handled. ---------------------------------------- Bug #4576: Range#step miss the last value, if end-exclusive and has float number http://redmine.ruby-lang.org/issues/4576 Author: Joey Zhou Status: Closed Priority: Normal Assignee: Category: Target version: ruby -v: - =begin Hi, I find that: * if: range.exclude_end? == true * and: any one in [begin_obj, end_obj, step] is a true Float(f.to_i != f) * and: unless begin_obj + step*int == end_obj * then: the result will miss the last value. for example: p (1...6.3).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0], no 6.0 p (1.1...6).step.to_a # => [1.1, 2.1, 3.1, 4.1], no 5.1 p (1...6).step(1.1).to_a # => [1.0, 2.1, 3.2, 4.300000000000001], no 5.4 p (1.0...6.6).step(1.9).to_a # => [1.0, 2.9], no 4.8 p (1.0...6.7).step(1.9).to_a # => [1.0, 2.9, 4.8] p (1.0...6.8).step(1.9).to_a # => [1.0, 2.9, 4.8], no 6.7 Maybe the #step is ok on integers, but there's something wrong if the range is end-exclusive and contain float numbers. =end -- http://redmine.ruby-lang.org