ruby-changes:44751
From: nobu <ko1@a...>
Date: Fri, 18 Nov 2016 15:29:56 +0900 (JST)
Subject: [ruby-changes:44751] nobu:r56824 (trunk): internal.h: round macros
nobu 2016-11-18 15:29:51 +0900 (Fri, 18 Nov 2016) New Revision: 56824 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56824 Log: internal.h: round macros * internal.h (ROUND_FUNC, ROUND_CALL): macros wrapping round functions. Modified files: trunk/internal.h trunk/numeric.c trunk/rational.c Index: internal.h =================================================================== --- internal.h (revision 56823) +++ internal.h (revision 56824) @@ -1151,8 +1151,14 @@ enum ruby_num_rounding_mode { https://github.com/ruby/ruby/blob/trunk/internal.h#L1151 RUBY_NUM_ROUND_HALF_EVEN, RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT }; -#define ROUND_TO(mode, up, even) \ - ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : up) +#define ROUND_TO(mode, even, up) \ + ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \ + up) +#define ROUND_FUNC(mode, name) \ + ROUND_TO(mode, name##_half_even, name##_half_up) +#define ROUND_CALL(mode, name, args) \ + ROUND_TO(mode, name##_half_even args, \ + name##_half_up args) int rb_num_to_uint(VALUE val, unsigned int *ret); VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl); Index: numeric.c =================================================================== --- numeric.c (revision 56823) +++ numeric.c (revision 56824) @@ -99,6 +99,7 @@ round_half_up(double x, double s) https://github.com/ruby/ruby/blob/trunk/numeric.c#L99 #ifdef HAVE_ROUND f = round(xs); + if (s == 1.0) return f; #endif if (x > 0) { #ifndef HAVE_ROUND @@ -2033,6 +2034,18 @@ int_round_half_up(SIGNED_VALUE x, SIGNED https://github.com/ruby/ruby/blob/trunk/numeric.c#L2034 return (x + y / 2) / y * y; } +static int +int_half_p_half_even(VALUE num, VALUE n, VALUE f) +{ + return (int)int_odd_p(rb_int_idiv(n, f)); +} + +static int +int_half_p_half_up(VALUE num, VALUE n, VALUE f) +{ + return int_pos_p(num); +} + /* * Assumes num is an Integer, ndigits <= 0 */ @@ -2050,9 +2063,7 @@ rb_int_round(VALUE num, int ndigits, enu https://github.com/ruby/ruby/blob/trunk/numeric.c#L2063 SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f); int neg = x < 0; if (neg) x = -x; - x = ROUND_TO(mode, - int_round_half_up(x, y), - int_round_half_even(x, y)); + x = ROUND_CALL(mode, int_round, (x, y)); if (neg) x = -x; return LONG2NUM(x); } @@ -2065,10 +2076,7 @@ rb_int_round(VALUE num, int ndigits, enu https://github.com/ruby/ruby/blob/trunk/numeric.c#L2076 n = rb_int_minus(num, r); r = rb_int_cmp(r, h); if (FIXNUM_POSITIVE_P(r) || - (FIXNUM_ZERO_P(r) && - ROUND_TO(mode, - int_pos_p(num), - (SIGNED_VALUE) int_odd_p(rb_int_idiv(n, f))))) { + (FIXNUM_ZERO_P(r) && ROUND_CALL(mode, int_half_p, (num, n, f)))) { n = rb_int_plus(n, f); } return n; @@ -2199,14 +2207,12 @@ flo_round(int argc, VALUE *argv, VALUE n https://github.com/ruby/ruby/blob/trunk/numeric.c#L2207 } number = RFLOAT_VALUE(num); if (ndigits == 0) { - x = ROUND_TO(mode, - round(number), round_half_even(number, 1.0)); + x = ROUND_CALL(mode, round, (number, 1.0)); return dbl2ival(x); } if (float_invariant_round(number, ndigits, &num)) return num; f = pow(10, ndigits); - x = ROUND_TO(mode, - round_half_up(number, f), round_half_even(number, f)); + x = ROUND_CALL(mode, round, (number, f)); return DBL2NUM(x / f); } Index: rational.c =================================================================== --- rational.c (revision 56823) +++ rational.c (revision 56824) @@ -1481,9 +1481,7 @@ nurat_round_n(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/rational.c#L1481 enum ruby_num_rounding_mode mode = ( argc = rb_scan_args(argc, argv, "*:", NULL, &opt), rb_num_get_rounding_option(opt)); - VALUE (*round_func)(VALUE) = - ROUND_TO(mode, - nurat_round_half_up, nurat_round_half_even); + VALUE (*round_func)(VALUE) = ROUND_FUNC(mode, nurat_round); return f_round_common(argc, argv, self, round_func); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/