From db8368fa865b7a3c74bc6d96f50597440e5f0f57 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 11 Mar 2024 10:13:36 +0900 Subject: [PATCH] numeric.c: remove bit operations methods from Float class; #6197 mruby used to use float numbers for overflown integers before we implemented big integers. Now we don't need bit operations for float numbers anymore. Also removed tests for shift operations for float numbers. --- src/numeric.c | 146 ------------------------------------------------ test/t/float.rb | 22 -------- 2 files changed, 168 deletions(-) diff --git a/src/numeric.c b/src/numeric.c index 50bf8c338..53a71e885 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -612,136 +612,6 @@ flo_eq(mrb_state *mrb, mrb_value x) } } -static int64_t -value_int64(mrb_state *mrb, mrb_value x) -{ - switch (mrb_type(x)) { - case MRB_TT_INTEGER: - return (int64_t)mrb_integer(x); - case MRB_TT_FLOAT: - { - double f = mrb_float(x); - - if ((mrb_float)INT64_MAX >= f && f >= (mrb_float)INT64_MIN) - return (int64_t)f; - } - default: - mrb_raise(mrb, E_TYPE_ERROR, "cannot convert to Integer"); - break; - } - /* not reached */ - return 0; -} - -static mrb_value -int64_value(mrb_state *mrb, int64_t v) -{ - if (!TYPED_FIXABLE(v,int64_t)) { - mrb_int_overflow(mrb, "bit operation"); - } - return mrb_fixnum_value((mrb_int)v); -} - -static mrb_value -flo_rev(mrb_state *mrb, mrb_value x) -{ - int64_t v1 = value_int64(mrb, x); - return int64_value(mrb, ~v1); -} - -static mrb_value -flo_and(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - int64_t v1, v2; - - v1 = value_int64(mrb, x); - v2 = value_int64(mrb, y); - return int64_value(mrb, v1 & v2); -} - -static mrb_value -flo_or(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - int64_t v1, v2; - - v1 = value_int64(mrb, x); - v2 = value_int64(mrb, y); - return int64_value(mrb, v1 | v2); -} - -static mrb_value -flo_xor(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - int64_t v1, v2; - - v1 = value_int64(mrb, x); - v2 = value_int64(mrb, y); - return int64_value(mrb, v1 ^ v2); -} - -static mrb_value -flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) -{ - mrb_float val; - - if (width == 0) { - return x; - } - val = mrb_float(x); - if (width < -MRB_INT_BIT/2) { - if (val < 0) return mrb_fixnum_value(-1); - return mrb_fixnum_value(0); - } - if (width < 0) { - while (width++) { - val /= 2; - if (val < 1.0) { - val = 0; - break; - } - } -#if defined(_ISOC99_SOURCE) - val = trunc(val); -#else - if (val > 0){ - val = floor(val); - } - else { - val = ceil(val); - } -#endif - if (val == 0 && mrb_float(x) < 0) { - return mrb_fixnum_value(-1); - } - } - else { - while (width--) { - val *= 2; - } - } - if (FIXABLE_FLOAT(val)) - return mrb_int_value(mrb, (mrb_int)val); - return mrb_float_value(mrb, val); -} - -static mrb_value -flo_rshift(mrb_state *mrb, mrb_value x) -{ - mrb_int width = mrb_as_int(mrb, mrb_get_arg1(mrb)); - if (width == MRB_INT_MIN) return flo_shift(mrb, x, -MRB_INT_BIT); - return flo_shift(mrb, x, -width); -} - -static mrb_value -flo_lshift(mrb_state *mrb, mrb_value x) -{ - mrb_int width = mrb_as_int(mrb, mrb_get_arg1(mrb)); - return flo_shift(mrb, x, width); -} - /* 15.2.9.3.13 */ /* * Document-method: Float#to_f @@ -1372,19 +1242,9 @@ int_rev(mrb_state *mrb, mrb_value num) return mrb_int_value(mrb, ~val); } -#ifdef MRB_NO_FLOAT #define bit_op(x,y,op1,op2) do {\ return mrb_int_value(mrb, (mrb_integer(x) op2 mrb_integer(y)));\ } while(0) -#else -static mrb_value flo_and(mrb_state *mrb, mrb_value x); -static mrb_value flo_or(mrb_state *mrb, mrb_value x); -static mrb_value flo_xor(mrb_state *mrb, mrb_value x); -#define bit_op(x,y,op1,op2) do {\ - if (mrb_integer_p(y)) return mrb_int_value(mrb, (mrb_integer(x) op2 mrb_integer(y))); \ - return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_integer(x)));\ -} while(0) -#endif /* 15.2.8.3.9 */ /* @@ -2287,12 +2147,6 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method_id(mrb, fl, MRB_OPSYM(gt), num_gt, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, fl, MRB_OPSYM(ge), num_ge, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, fl, MRB_OPSYM(eq), flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */ - mrb_define_method_id(mrb, fl, MRB_OPSYM(neg), flo_rev, MRB_ARGS_NONE()); - mrb_define_method_id(mrb, fl, MRB_OPSYM(and), flo_and, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, fl, MRB_OPSYM(or), flo_or, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, fl, MRB_OPSYM(xor), flo_xor, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, fl, MRB_OPSYM(rshift), flo_rshift, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, fl, MRB_OPSYM(lshift), flo_lshift, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, fl, MRB_SYM(ceil), flo_ceil, MRB_ARGS_OPT(1)); /* 15.2.9.3.8 */ mrb_define_method_id(mrb, fl, MRB_SYM_Q(finite), flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ mrb_define_method_id(mrb, fl, MRB_SYM(floor), flo_floor, MRB_ARGS_OPT(1)); /* 15.2.9.3.10 */ diff --git a/test/t/float.rb b/test/t/float.rb index 1a7f6c99a..72945d250 100644 --- a/test/t/float.rb +++ b/test/t/float.rb @@ -239,28 +239,6 @@ assert('Float#nan?') do assert_not_predicate(-1.0/0.0, :nan?) end -assert('Float#<<') do - # Left Shift by one - assert_equal 46, 23.0 << 1 - - # Left Shift by a negative is Right Shift - assert_equal 23, 46.0 << -1 -end - -assert('Float#>>') do - # Right Shift by one - assert_equal 23, 46.0 >> 1 - - # Right Shift by a negative is Left Shift - assert_equal 46, 23.0 >> -1 - - # Don't raise on large Right Shift - assert_equal 0, 23.0 >> 128 - - # Don't raise on large Right Shift - assert_equal(-1, -23.0 >> 128) -end - assert('Float#to_s') do uses_float = 4e38.infinite? # enable MRB_USE_FLOAT32?