Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #2841 > unrolled thread
| Started by | Joey Zhou <yimutang@gmail.com> |
|---|---|
| First post | 2011-04-14 07:42 -0500 |
| Last post | 2011-04-14 13:01 -0500 |
| Articles | 5 — 4 participants |
Back to article view | Back to comp.lang.ruby
Exclusive float range, Range#step result in counterintuitive result Joey Zhou <yimutang@gmail.com> - 2011-04-14 07:42 -0500
Re: Exclusive float range, Range#step result in counterintuitive result Joey Zhou <yimutang@gmail.com> - 2011-04-14 07:58 -0500
Re: Exclusive float range, Range#step result in counterintuitive result Robert Klemme <shortcutter@googlemail.com> - 2011-04-14 08:28 -0500
Re: Exclusive float range, Range#step result in counterintuitive result 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-14 11:47 -0500
Re: Exclusive float range, Range#step result in counterintuitive result Su Zhang <zhangsu@live.com> - 2011-04-14 13:01 -0500
| From | Joey Zhou <yimutang@gmail.com> |
|---|---|
| Date | 2011-04-14 07:42 -0500 |
| Subject | Exclusive float range, Range#step result in counterintuitive result |
| Message-ID | <a1e005bd5510e4b0931e34c1d6147eaf@ruby-forum.com> |
Hi everybody,
I find that:
if
range.exclude_end? == true
and
[begin_obj, end_obj, step].grep(Float) != []
and
[begin_obj, end_obj, step].any? {|f| f != f.to_i}
then
# result will miss the last one
end
for example:
p (1...6.3).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0], missing 6.0
p (1.1...6).step.to_a # => [1.1, 2.1, 3.1, 4.1], missing 5.1
p (1...6).step(1.1).to_a # => [1.0, 2.1, 3.2, 4.300000000000001],
missing 5.4
p (1.0...6.6).step(1.9).to_a # => [1.0, 2.9], missing 4.8
p (1.0...6.7).step(1.9).to_a # => [1.0, 2.9, 4.8], 6.7 == 4.8 + 1.9,
it's ok
The results seem so counterintuitive, is it a bug? Maybe I should report
it?
Thank you!
Joey
--
Posted via http://www.ruby-forum.com/.
[toc] | [next] | [standalone]
| From | Joey Zhou <yimutang@gmail.com> |
|---|---|
| Date | 2011-04-14 07:58 -0500 |
| Message-ID | <d54e3dd816891c03898fcb2db40b3ae2@ruby-forum.com> |
| In reply to | #2841 |
and another one on Range#max, also *exclusive* range:
p (1...9.3).max # cannot exclude non Integer end value (TypeError)
p (1...9.3).max {|a,b| a <=> b} #=> 9
I think the result should be the same. Maybe the first one should
also return 9, not an error.
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-04-14 08:28 -0500 |
| Message-ID | <BANLkTi=-qJWaDLHkeEDv3Vnj_jmP_mNB3g@mail.gmail.com> |
| In reply to | #2841 |
On Thu, Apr 14, 2011 at 2:42 PM, Joey Zhou <yimutang@gmail.com> wrote:
> Hi everybody,
>
> I find that:
>
> if
> range.exclude_end? == true
> and
> [begin_obj, end_obj, step].grep(Float) != []
> and
> [begin_obj, end_obj, step].any? {|f| f != f.to_i}
> then
> # result will miss the last one
> end
>
> for example:
>
> p (1...6.3).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0], missing 6.0
> p (1.1...6).step.to_a # => [1.1, 2.1, 3.1, 4.1], missing 5.1
> p (1...6).step(1.1).to_a # => [1.0, 2.1, 3.2, 4.300000000000001],
> missing 5.4
>
> p (1.0...6.6).step(1.9).to_a # => [1.0, 2.9], missing 4.8
> p (1.0...6.7).step(1.9).to_a # => [1.0, 2.9, 4.8], 6.7 == 4.8 + 1.9,
> it's ok
>
> The results seem so counterintuitive, is it a bug? Maybe I should report
> it?
Hmmm... Float and Range generally don't mix very well. Considering
this the results seem at least consistent - if not expected:
irb(main):001:0> (1.0...6.6).step(1.9).to_a
=> [1.0, 2.9]
irb(main):002:0> (1.0..6.6).step(1.9).to_a
=> [1.0, 2.9, 4.8]
Line 2 cannot go beyond 4.8 because then it would pass 6.6, so the
last value which can really be returned is 4.8. The third dot removes
that value from the list.
It's at least a tad weird. +0.5 for opening a bug.
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-14 11:47 -0500 |
| Message-ID | <ea9c70684501a99b8ceb08fb50b72503@ruby-forum.com> |
| In reply to | #2841 |
Joey Zhou wrote in post #992758: > > The results seem so counterintuitive, is it a bug? Maybe I should report > it? > By definition, floats cannot be used in ranges. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Su Zhang <zhangsu@live.com> |
|---|---|
| Date | 2011-04-14 13:01 -0500 |
| Message-ID | <ffe293204df05d4f329c392eb4767bb6@ruby-forum.com> |
| In reply to | #2841 |
This looks like a bug to me.
(The problem exists as of 1.9.2-p180.)
In <range.c>, `range_step' is the implementation of Range#step. It calls
`ruby_float_step', which is implemented in <numeric.c>, to handle float
stepping.
The call looks like this:
else if (ruby_float_step(b, e, step, EXCL(range))) {
/* done */
}
The problem is that it passes the `exclude_end?' property of the range
to `ruby_float_step', in our case it is false. Inside the implementation
of `ruby_float_step' is something like:
n = floor(n + err);
if (!excl) n++;
for (i=0; i<n; i++) {
rb_yield(DBL2NUM(i*unit+beg));
}
And excl is the last parameter. Clearly if the end value of the range is
x, then the iteration only goes to floor(x)-1.
On the other hand -
p 1.step(6.3).to_a # => [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
This works since `num_step', again implemented in <numeric.c>,
explicitly passes a false to excl:
else if (!ruby_float_step(from, to, step, FALSE)) {
...
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web