ruby-changes:25605
From: mame <ko1@a...>
Date: Thu, 15 Nov 2012 22:51:05 +0900 (JST)
Subject: [ruby-changes:25605] mame:r37662 (trunk): * range.c (range_bsearch): fix some bugs: a documentation bug, a wrong
mame 2012-11-15 22:50:55 +0900 (Thu, 15 Nov 2012) New Revision: 37662 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37662 Log: * range.c (range_bsearch): fix some bugs: a documentation bug, a wrong condition, missed break in switch/case, and workaround for GCC optimization. See [ruby-core:49364] in detail. A great patch from Heesob Park. [Bug #7352] [Feature #4766] * array.c (rb_ary_bsearch): fix similar bug (missed break). * test/ruby/test_range.rb: add two test cases for above. Modified files: trunk/ChangeLog trunk/array.c trunk/range.c trunk/test/ruby/test_range.rb Index: array.c =================================================================== --- array.c (revision 37661) +++ array.c (revision 37662) @@ -2451,7 +2451,7 @@ else if (rb_obj_is_kind_of(v, rb_cNumeric)) { switch (rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0))) { case 0: return val; - case 1: smaller = 1; + case 1: smaller = 1; break; case -1: smaller = 0; } } Index: ChangeLog =================================================================== --- ChangeLog (revision 37661) +++ ChangeLog (revision 37662) @@ -1,3 +1,14 @@ +Thu Nov 15 22:39:32 2012 Yusuke Endoh <mame@t...> + + * range.c (range_bsearch): fix some bugs: a documentation bug, a wrong + condition, missed break in switch/case, and workaround for GCC + optimization. See [ruby-core:49364] in detail. A great patch from + Heesob Park. [Bug #7352] [Feature #4766] + + * array.c (rb_ary_bsearch): fix similar bug (missed break). + + * test/ruby/test_range.rb: add two test cases for above. + Thu Nov 15 22:41:57 2012 Koichi Sasada <ko1@a...> * vm_exec.h (GENTRY): GENTRY should be pointer size. Index: range.c =================================================================== --- range.c (revision 37661) +++ range.c (revision 37662) @@ -513,9 +513,9 @@ * satisfies the condition, it returns nil. * * ary = [0, 100, 100, 100, 200] - * (0..4).bsearch {|i| 100 - i } #=> 1, 2 or 3 - * (0..4).bsearch {|i| 300 - i } #=> nil - * (0..4).bsearch {|i| 50 - i } #=> nil + * (0..4).bsearch {|i| 100 - ary[i] } #=> 1, 2 or 3 + * (0..4).bsearch {|i| 300 - ary[i] } #=> nil + * (0..4).bsearch {|i| 50 - ary[i] } #=> nil * * You must not mix the two modes at a time; the block must always * return either true/false, or always return a number. It is @@ -543,10 +543,10 @@ smaller = 0; \ } \ else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \ - switch (rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)) < 0) { \ + switch (rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0))) { \ case 0: return val; \ - case 1: smaller = 1; \ - case -1: smaller = 0; \ + case -1: smaller = 1; break; \ + case 1: smaller = 0; \ } \ } \ else { \ @@ -586,6 +586,7 @@ double high = RFLOAT_VALUE(rb_Float(end)); double mid, org_high; int count; + org_high = high; #ifdef FLT_RADIX #ifdef DBL_MANT_DIG #define BSEARCH_MAXCOUNT (((FLT_RADIX) - 1) * (DBL_MANT_DIG + DBL_MAX_EXP) + 100) @@ -646,7 +647,7 @@ } if (isinf(low) && low < 0) { /* the range is (-INFINITY..high) */ - double nlow = -1.0, dec; + volatile double nlow = -1.0, dec; if (nlow > high) nlow = high; count = BSEARCH_MAXCOUNT; /* find lower bound by checking low, low*2, low*4, ... */ @@ -697,7 +698,6 @@ binsearch: /* find the desired value within low..high */ /* where low is not -INFINITY and high is not INFINITY */ - org_high = high; count = BSEARCH_MAXCOUNT; while (low < high && count >= 0) { mid = low + ((high - low) / 2); Index: test/ruby/test_range.rb =================================================================== --- test/ruby/test_range.rb (revision 37661) +++ test/ruby/test_range.rb (revision 37662) @@ -417,6 +417,9 @@ v = (-inf..0).bsearch {|x| x > -Float::MAX } assert_operator(-Float::MAX, :<, v) assert_equal(nil, v.infinite?) + + assert_in_delta(1.0, (0.0..inf).bsearch {|x| Math.log(x) >= 0 }) + assert_in_delta(7.0, (0.0..10).bsearch {|x| 7.0 - x }) end def test_bsearch_for_bignum -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/