Fix ArithmeticSequence#last and ArithmeticSequence#each for non-integer sequences (#3870)
[Bug #17218] [ruby-core:100312]
This commit is contained in:
parent
cacdf2681d
commit
fad3023e94
Notes:
git
2020-12-09 18:49:23 +09:00
Merged-By: mrkn <mrkn@ruby-lang.org>
@ -4823,6 +4823,7 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
|||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h
|
||||||
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/string.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/string.h
|
||||||
@ -4989,6 +4990,7 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
|
|||||||
enumerator.$(OBJEXT): {$(VPATH)}missing.h
|
enumerator.$(OBJEXT): {$(VPATH)}missing.h
|
||||||
enumerator.$(OBJEXT): {$(VPATH)}onigmo.h
|
enumerator.$(OBJEXT): {$(VPATH)}onigmo.h
|
||||||
enumerator.$(OBJEXT): {$(VPATH)}oniguruma.h
|
enumerator.$(OBJEXT): {$(VPATH)}oniguruma.h
|
||||||
|
enumerator.$(OBJEXT): {$(VPATH)}ruby_assert.h
|
||||||
enumerator.$(OBJEXT): {$(VPATH)}st.h
|
enumerator.$(OBJEXT): {$(VPATH)}st.h
|
||||||
enumerator.$(OBJEXT): {$(VPATH)}subst.h
|
enumerator.$(OBJEXT): {$(VPATH)}subst.h
|
||||||
error.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
|
error.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
|
||||||
|
99
enumerator.c
99
enumerator.c
@ -26,6 +26,7 @@
|
|||||||
#include "internal/imemo.h"
|
#include "internal/imemo.h"
|
||||||
#include "internal/numeric.h"
|
#include "internal/numeric.h"
|
||||||
#include "internal/range.h"
|
#include "internal/range.h"
|
||||||
|
#include "internal/rational.h"
|
||||||
#include "ruby/ruby.h"
|
#include "ruby/ruby.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3601,6 +3602,88 @@ arith_seq_first(int argc, VALUE *argv, VALUE self)
|
|||||||
return rb_call_super(argc, argv);
|
return rb_call_super(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
num_plus(VALUE a, VALUE b)
|
||||||
|
{
|
||||||
|
if (RB_INTEGER_TYPE_P(a)) {
|
||||||
|
return rb_int_plus(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(a)) {
|
||||||
|
return rb_float_plus(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_TYPE_P(a, T_RATIONAL)) {
|
||||||
|
return rb_rational_plus(a, b);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return rb_funcallv(a, '+', 1, &b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
num_minus(VALUE a, VALUE b)
|
||||||
|
{
|
||||||
|
if (RB_INTEGER_TYPE_P(a)) {
|
||||||
|
return rb_int_minus(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(a)) {
|
||||||
|
return rb_float_minus(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_TYPE_P(a, T_RATIONAL)) {
|
||||||
|
return rb_rational_minus(a, b);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return rb_funcallv(a, '-', 1, &b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
num_mul(VALUE a, VALUE b)
|
||||||
|
{
|
||||||
|
if (RB_INTEGER_TYPE_P(a)) {
|
||||||
|
return rb_int_mul(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(a)) {
|
||||||
|
return rb_float_mul(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_TYPE_P(a, T_RATIONAL)) {
|
||||||
|
return rb_rational_mul(a, b);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return rb_funcallv(a, '*', 1, &b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
num_idiv(VALUE a, VALUE b)
|
||||||
|
{
|
||||||
|
VALUE q;
|
||||||
|
if (RB_INTEGER_TYPE_P(a)) {
|
||||||
|
q = rb_int_idiv(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(a)) {
|
||||||
|
q = rb_float_div(a, b);
|
||||||
|
}
|
||||||
|
else if (RB_TYPE_P(a, T_RATIONAL)) {
|
||||||
|
q = rb_rational_div(a, b);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
q = rb_funcallv(a, idDiv, 1, &b);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RB_INTEGER_TYPE_P(q)) {
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(q)) {
|
||||||
|
return rb_float_floor(q, 0);
|
||||||
|
}
|
||||||
|
else if (RB_TYPE_P(q, T_RATIONAL)) {
|
||||||
|
return rb_rational_floor(q, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return rb_funcall(q, rb_intern("floor"), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* aseq.last -> num or nil
|
* aseq.last -> num or nil
|
||||||
@ -3625,7 +3708,7 @@ arith_seq_last(int argc, VALUE *argv, VALUE self)
|
|||||||
b = arith_seq_begin(self);
|
b = arith_seq_begin(self);
|
||||||
s = arith_seq_step(self);
|
s = arith_seq_step(self);
|
||||||
|
|
||||||
len_1 = rb_int_idiv(rb_int_minus(e, b), s);
|
len_1 = num_idiv(num_minus(e, b), s);
|
||||||
if (rb_num_negative_int_p(len_1)) {
|
if (rb_num_negative_int_p(len_1)) {
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
@ -3633,9 +3716,9 @@ arith_seq_last(int argc, VALUE *argv, VALUE self)
|
|||||||
return rb_ary_new_capa(0);
|
return rb_ary_new_capa(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
last = rb_int_plus(b, rb_int_mul(s, len_1));
|
last = num_plus(b, num_mul(s, len_1));
|
||||||
if ((last_is_adjusted = arith_seq_exclude_end_p(self) && rb_equal(last, e))) {
|
if ((last_is_adjusted = arith_seq_exclude_end_p(self) && rb_equal(last, e))) {
|
||||||
last = rb_int_minus(last, s);
|
last = num_minus(last, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
@ -3844,22 +3927,22 @@ arith_seq_each(VALUE self)
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
len_1 = rb_int_idiv(rb_int_minus(e, c), s);
|
len_1 = num_idiv(num_minus(e, c), s);
|
||||||
last = rb_int_plus(c, rb_int_mul(s, len_1));
|
last = num_plus(c, num_mul(s, len_1));
|
||||||
if (x && rb_equal(last, e)) {
|
if (x && rb_equal(last, e)) {
|
||||||
last = rb_int_minus(last, s);
|
last = num_minus(last, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_num_negative_int_p(s)) {
|
if (rb_num_negative_int_p(s)) {
|
||||||
while (NUM_GE(c, last)) {
|
while (NUM_GE(c, last)) {
|
||||||
rb_yield(c);
|
rb_yield(c);
|
||||||
c = rb_int_plus(c, s);
|
c = num_plus(c, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (NUM_GE(last, c)) {
|
while (NUM_GE(last, c)) {
|
||||||
rb_yield(c);
|
rb_yield(c);
|
||||||
c = rb_int_plus(c, s);
|
c = num_plus(c, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ VALUE rb_float_uminus(VALUE num);
|
|||||||
VALUE rb_int_plus(VALUE x, VALUE y);
|
VALUE rb_int_plus(VALUE x, VALUE y);
|
||||||
VALUE rb_float_plus(VALUE x, VALUE y);
|
VALUE rb_float_plus(VALUE x, VALUE y);
|
||||||
VALUE rb_int_minus(VALUE x, VALUE y);
|
VALUE rb_int_minus(VALUE x, VALUE y);
|
||||||
|
VALUE rb_float_minus(VALUE x, VALUE y);
|
||||||
VALUE rb_int_mul(VALUE x, VALUE y);
|
VALUE rb_int_mul(VALUE x, VALUE y);
|
||||||
VALUE rb_float_mul(VALUE x, VALUE y);
|
VALUE rb_float_mul(VALUE x, VALUE y);
|
||||||
VALUE rb_float_div(VALUE x, VALUE y);
|
VALUE rb_float_div(VALUE x, VALUE y);
|
||||||
@ -79,6 +80,7 @@ int rb_int_positive_p(VALUE num);
|
|||||||
int rb_int_negative_p(VALUE num);
|
int rb_int_negative_p(VALUE num);
|
||||||
VALUE rb_num_pow(VALUE x, VALUE y);
|
VALUE rb_num_pow(VALUE x, VALUE y);
|
||||||
VALUE rb_float_ceil(VALUE num, int ndigits);
|
VALUE rb_float_ceil(VALUE num, int ndigits);
|
||||||
|
VALUE rb_float_floor(VALUE x, int ndigits);
|
||||||
VALUE rb_float_abs(VALUE flt);
|
VALUE rb_float_abs(VALUE flt);
|
||||||
static inline VALUE rb_num_compare_with_zero(VALUE num, ID mid);
|
static inline VALUE rb_num_compare_with_zero(VALUE num, ID mid);
|
||||||
static inline int rb_num_positive_int_p(VALUE num);
|
static inline int rb_num_positive_int_p(VALUE num);
|
||||||
|
@ -29,12 +29,14 @@ VALUE rb_rational_uminus(VALUE self);
|
|||||||
VALUE rb_rational_plus(VALUE self, VALUE other);
|
VALUE rb_rational_plus(VALUE self, VALUE other);
|
||||||
VALUE rb_rational_minus(VALUE self, VALUE other);
|
VALUE rb_rational_minus(VALUE self, VALUE other);
|
||||||
VALUE rb_rational_mul(VALUE self, VALUE other);
|
VALUE rb_rational_mul(VALUE self, VALUE other);
|
||||||
|
VALUE rb_rational_div(VALUE self, VALUE other);
|
||||||
VALUE rb_lcm(VALUE x, VALUE y);
|
VALUE rb_lcm(VALUE x, VALUE y);
|
||||||
VALUE rb_rational_reciprocal(VALUE x);
|
VALUE rb_rational_reciprocal(VALUE x);
|
||||||
VALUE rb_cstr_to_rat(const char *, int);
|
VALUE rb_cstr_to_rat(const char *, int);
|
||||||
VALUE rb_rational_abs(VALUE self);
|
VALUE rb_rational_abs(VALUE self);
|
||||||
VALUE rb_rational_cmp(VALUE self, VALUE other);
|
VALUE rb_rational_cmp(VALUE self, VALUE other);
|
||||||
VALUE rb_rational_pow(VALUE self, VALUE other);
|
VALUE rb_rational_pow(VALUE self, VALUE other);
|
||||||
|
VALUE rb_rational_floor(VALUE self, int ndigits);
|
||||||
VALUE rb_numeric_quo(VALUE x, VALUE y);
|
VALUE rb_numeric_quo(VALUE x, VALUE y);
|
||||||
VALUE rb_float_numerator(VALUE x);
|
VALUE rb_float_numerator(VALUE x);
|
||||||
VALUE rb_float_denominator(VALUE x);
|
VALUE rb_float_denominator(VALUE x);
|
||||||
|
53
numeric.c
53
numeric.c
@ -1078,8 +1078,8 @@ rb_float_plus(VALUE x, VALUE y)
|
|||||||
* Returns a new Float which is the difference of +float+ and +other+.
|
* Returns a new Float which is the difference of +float+ and +other+.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
flo_minus(VALUE x, VALUE y)
|
rb_float_minus(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
if (RB_TYPE_P(y, T_FIXNUM)) {
|
if (RB_TYPE_P(y, T_FIXNUM)) {
|
||||||
return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
|
return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
|
||||||
@ -1935,6 +1935,31 @@ flo_prev_float(VALUE vx)
|
|||||||
return flo_nextafter(vx, -HUGE_VAL);
|
return flo_nextafter(vx, -HUGE_VAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_float_floor(VALUE num, int ndigits)
|
||||||
|
{
|
||||||
|
double number, f;
|
||||||
|
number = RFLOAT_VALUE(num);
|
||||||
|
if (number == 0.0) {
|
||||||
|
return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
|
||||||
|
}
|
||||||
|
if (ndigits > 0) {
|
||||||
|
int binexp;
|
||||||
|
frexp(number, &binexp);
|
||||||
|
if (float_round_overflow(ndigits, binexp)) return num;
|
||||||
|
if (number > 0.0 && float_round_underflow(ndigits, binexp))
|
||||||
|
return DBL2NUM(0.0);
|
||||||
|
f = pow(10, ndigits);
|
||||||
|
f = floor(number * f) / f;
|
||||||
|
return DBL2NUM(f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num = dbl2ival(floor(number));
|
||||||
|
if (ndigits < 0) num = rb_int_floor(num, ndigits);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* float.floor([ndigits]) -> integer or float
|
* float.floor([ndigits]) -> integer or float
|
||||||
@ -1977,31 +2002,11 @@ flo_prev_float(VALUE vx)
|
|||||||
static VALUE
|
static VALUE
|
||||||
flo_floor(int argc, VALUE *argv, VALUE num)
|
flo_floor(int argc, VALUE *argv, VALUE num)
|
||||||
{
|
{
|
||||||
double number, f;
|
|
||||||
int ndigits = 0;
|
int ndigits = 0;
|
||||||
|
|
||||||
if (rb_check_arity(argc, 0, 1)) {
|
if (rb_check_arity(argc, 0, 1)) {
|
||||||
ndigits = NUM2INT(argv[0]);
|
ndigits = NUM2INT(argv[0]);
|
||||||
}
|
}
|
||||||
number = RFLOAT_VALUE(num);
|
return rb_float_floor(num, ndigits);
|
||||||
if (number == 0.0) {
|
|
||||||
return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
|
|
||||||
}
|
|
||||||
if (ndigits > 0) {
|
|
||||||
int binexp;
|
|
||||||
frexp(number, &binexp);
|
|
||||||
if (float_round_overflow(ndigits, binexp)) return num;
|
|
||||||
if (number > 0.0 && float_round_underflow(ndigits, binexp))
|
|
||||||
return DBL2NUM(0.0);
|
|
||||||
f = pow(10, ndigits);
|
|
||||||
f = floor(number * f) / f;
|
|
||||||
return DBL2NUM(f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
num = dbl2ival(floor(number));
|
|
||||||
if (ndigits < 0) num = rb_int_floor(num, ndigits);
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5749,7 +5754,7 @@ Init_Numeric(void)
|
|||||||
rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
|
rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
|
||||||
rb_define_method(rb_cFloat, "-@", rb_float_uminus, 0);
|
rb_define_method(rb_cFloat, "-@", rb_float_uminus, 0);
|
||||||
rb_define_method(rb_cFloat, "+", rb_float_plus, 1);
|
rb_define_method(rb_cFloat, "+", rb_float_plus, 1);
|
||||||
rb_define_method(rb_cFloat, "-", flo_minus, 1);
|
rb_define_method(rb_cFloat, "-", rb_float_minus, 1);
|
||||||
rb_define_method(rb_cFloat, "*", rb_float_mul, 1);
|
rb_define_method(rb_cFloat, "*", rb_float_mul, 1);
|
||||||
rb_define_method(rb_cFloat, "/", rb_float_div, 1);
|
rb_define_method(rb_cFloat, "/", rb_float_div, 1);
|
||||||
rb_define_method(rb_cFloat, "quo", flo_quo, 1);
|
rb_define_method(rb_cFloat, "quo", flo_quo, 1);
|
||||||
|
28
rational.c
28
rational.c
@ -894,8 +894,8 @@ rb_rational_mul(VALUE self, VALUE other)
|
|||||||
* Rational(9, 8) / 4 #=> (9/32)
|
* Rational(9, 8) / 4 #=> (9/32)
|
||||||
* Rational(20, 9) / 9.8 #=> 0.22675736961451246
|
* Rational(20, 9) / 9.8 #=> 0.22675736961451246
|
||||||
*/
|
*/
|
||||||
static VALUE
|
VALUE
|
||||||
nurat_div(VALUE self, VALUE other)
|
rb_rational_div(VALUE self, VALUE other)
|
||||||
{
|
{
|
||||||
if (RB_INTEGER_TYPE_P(other)) {
|
if (RB_INTEGER_TYPE_P(other)) {
|
||||||
if (f_zero_p(other))
|
if (f_zero_p(other))
|
||||||
@ -947,10 +947,10 @@ nurat_fdiv(VALUE self, VALUE other)
|
|||||||
{
|
{
|
||||||
VALUE div;
|
VALUE div;
|
||||||
if (f_zero_p(other))
|
if (f_zero_p(other))
|
||||||
return nurat_div(self, rb_float_new(0.0));
|
return rb_rational_div(self, rb_float_new(0.0));
|
||||||
if (FIXNUM_P(other) && other == LONG2FIX(1))
|
if (FIXNUM_P(other) && other == LONG2FIX(1))
|
||||||
return nurat_to_f(self);
|
return nurat_to_f(self);
|
||||||
div = nurat_div(self, other);
|
div = rb_rational_div(self, other);
|
||||||
if (RB_TYPE_P(div, T_RATIONAL))
|
if (RB_TYPE_P(div, T_RATIONAL))
|
||||||
return nurat_to_f(div);
|
return nurat_to_f(div);
|
||||||
if (RB_FLOAT_TYPE_P(div))
|
if (RB_FLOAT_TYPE_P(div))
|
||||||
@ -1377,7 +1377,7 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
|
|||||||
|
|
||||||
s = (*func)(s);
|
s = (*func)(s);
|
||||||
|
|
||||||
s = nurat_div(f_rational_new_bang1(CLASS_OF(self), s), b);
|
s = rb_rational_div(f_rational_new_bang1(CLASS_OF(self), s), b);
|
||||||
|
|
||||||
if (RB_TYPE_P(s, T_RATIONAL) && FIX2INT(rb_int_cmp(n, ONE)) < 0)
|
if (RB_TYPE_P(s, T_RATIONAL) && FIX2INT(rb_int_cmp(n, ONE)) < 0)
|
||||||
s = nurat_truncate(s);
|
s = nurat_truncate(s);
|
||||||
@ -1385,6 +1385,18 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_rational_floor(VALUE self, int ndigits)
|
||||||
|
{
|
||||||
|
if (ndigits == 0) {
|
||||||
|
return nurat_floor(self);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VALUE n = INT2NUM(ndigits);
|
||||||
|
return f_round_common(1, &n, self, nurat_floor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* rat.floor([ndigits]) -> integer or rational
|
* rat.floor([ndigits]) -> integer or rational
|
||||||
@ -2013,7 +2025,7 @@ rb_numeric_quo(VALUE x, VALUE y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
|
x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
|
||||||
return nurat_div(x, y);
|
return rb_rational_div(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
@ -2751,8 +2763,8 @@ Init_Rational(void)
|
|||||||
rb_define_method(rb_cRational, "+", rb_rational_plus, 1);
|
rb_define_method(rb_cRational, "+", rb_rational_plus, 1);
|
||||||
rb_define_method(rb_cRational, "-", rb_rational_minus, 1);
|
rb_define_method(rb_cRational, "-", rb_rational_minus, 1);
|
||||||
rb_define_method(rb_cRational, "*", rb_rational_mul, 1);
|
rb_define_method(rb_cRational, "*", rb_rational_mul, 1);
|
||||||
rb_define_method(rb_cRational, "/", nurat_div, 1);
|
rb_define_method(rb_cRational, "/", rb_rational_div, 1);
|
||||||
rb_define_method(rb_cRational, "quo", nurat_div, 1);
|
rb_define_method(rb_cRational, "quo", rb_rational_div, 1);
|
||||||
rb_define_method(rb_cRational, "fdiv", nurat_fdiv, 1);
|
rb_define_method(rb_cRational, "fdiv", nurat_fdiv, 1);
|
||||||
rb_define_method(rb_cRational, "**", nurat_expt, 1);
|
rb_define_method(rb_cRational, "**", nurat_expt, 1);
|
||||||
|
|
||||||
|
@ -264,6 +264,11 @@ class TestArithmeticSequence < Test::Unit::TestCase
|
|||||||
assert_instance_of Integer, res[1]
|
assert_instance_of Integer, res[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_last_bug17218
|
||||||
|
seq = (1.0997r .. 1.1r).step(0.0001r)
|
||||||
|
assert_equal(1.1r, seq.last, '[ruby-core:100312] [Bug #17218]')
|
||||||
|
end
|
||||||
|
|
||||||
def test_to_a
|
def test_to_a
|
||||||
assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1.step(10).to_a)
|
assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1.step(10).to_a)
|
||||||
assert_equal([1, 3, 5, 7, 9], 1.step(10, 2).to_a)
|
assert_equal([1, 3, 5, 7, 9], 1.step(10, 2).to_a)
|
||||||
@ -279,6 +284,11 @@ class TestArithmeticSequence < Test::Unit::TestCase
|
|||||||
'[ruby-core:90648] [Bug #15444]')
|
'[ruby-core:90648] [Bug #15444]')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_last_bug17218
|
||||||
|
seq = (1.0997r .. 1.1r).step(0.0001r)
|
||||||
|
assert_equal([1.0997r, 1.0998r, 1.0999r, 1.1r], seq.to_a, '[ruby-core:100312] [Bug #17218]')
|
||||||
|
end
|
||||||
|
|
||||||
def test_slice
|
def test_slice
|
||||||
seq = 1.step(10, 2)
|
seq = 1.step(10, 2)
|
||||||
assert_equal([[1, 3, 5], [7, 9]], seq.each_slice(3).to_a)
|
assert_equal([[1, 3, 5], [7, 9]], seq.each_slice(3).to_a)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user