12#include "ruby/internal/config.h"
29#include "internal/array.h"
30#include "internal/compilers.h"
31#include "internal/complex.h"
32#include "internal/enumerator.h"
33#include "internal/gc.h"
34#include "internal/hash.h"
35#include "internal/numeric.h"
36#include "internal/object.h"
37#include "internal/rational.h"
38#include "internal/string.h"
39#include "internal/util.h"
40#include "internal/variable.h"
50#define DBL_MIN 2.2250738585072014e-308
53#define DBL_MAX 1.7976931348623157e+308
56#define DBL_MIN_EXP (-1021)
59#define DBL_MAX_EXP 1024
62#define DBL_MIN_10_EXP (-307)
65#define DBL_MAX_10_EXP 308
71#define DBL_MANT_DIG 53
74#define DBL_EPSILON 2.2204460492503131e-16
77#ifndef USE_RB_INFINITY
78#elif !defined(WORDS_BIGENDIAN)
85#elif !defined(WORDS_BIGENDIAN)
99 x = f + (x - f >= 0.5);
103 x = f - (f - x >= 0.5);
110round_half_up(
double x,
double s)
112 double f, xs = x * s;
115 if (s == 1.0)
return f;
117 if ((
double)((f + 0.5) / s) <= x) f += 1;
121 if ((
double)((f - 0.5) / s) >= x) f -= 1;
128round_half_down(
double x,
double s)
130 double f, xs = x * s;
134 if ((
double)((f - 0.5) / s) >= x) f -= 1;
138 if ((
double)((f + 0.5) / s) <= x) f += 1;
145round_half_even(
double x,
double s)
147 double f, d, xs = x * s;
154 else if (d == 0.5 || ((
double)((f + 0.5) / s) <= x))
165 else if (d == 0.5 || ((
double)((f - 0.5) / s) >= x))
174static VALUE fix_lshift(
long,
unsigned long);
175static VALUE fix_rshift(
long,
unsigned long);
176static VALUE int_pow(
long x,
unsigned long y);
177static VALUE rb_int_floor(VALUE num,
int ndigits);
178static VALUE rb_int_ceil(VALUE num,
int ndigits);
179static VALUE flo_to_i(VALUE num);
180static int float_round_overflow(
int ndigits,
int binexp);
181static int float_round_underflow(
int ndigits,
int binexp);
185#define id_divmod idDivmod
186#define id_to_i idTo_i
197static ID id_to, id_by;
205enum ruby_num_rounding_mode
206rb_num_get_rounding_option(VALUE opts)
208 static ID round_kwds[1];
214 if (!round_kwds[0]) {
217 if (!
rb_get_kwargs(opts, round_kwds, 0, 1, &rounding))
goto noopt;
221 else if (
NIL_P(rounding)) {
226 if (
NIL_P(str))
goto invalid;
233 return RUBY_NUM_ROUND_HALF_UP;
237 return RUBY_NUM_ROUND_HALF_EVEN;
238 if (strncasecmp(s,
"down", 4) == 0)
239 return RUBY_NUM_ROUND_HALF_DOWN;
243 rb_raise(rb_eArgError,
"invalid rounding mode: % "PRIsVALUE, rounding);
246 return RUBY_NUM_ROUND_DEFAULT;
251rb_num_to_uint(VALUE val,
unsigned int *ret)
254#define NUMERR_NEGATIVE 2
255#define NUMERR_TOOLARGE 3
258#if SIZEOF_INT < SIZEOF_LONG
259 if (v > (
long)UINT_MAX)
return NUMERR_TOOLARGE;
261 if (v < 0)
return NUMERR_NEGATIVE;
262 *ret = (
unsigned int)v;
266 if (RB_BIGNUM_TYPE_P(val)) {
267 if (BIGNUM_NEGATIVE_P(val))
return NUMERR_NEGATIVE;
268#if SIZEOF_INT < SIZEOF_LONG
270 return NUMERR_TOOLARGE;
273 if (
rb_absint_size(val, NULL) >
sizeof(int))
return NUMERR_TOOLARGE;
281#define method_basic_p(klass) rb_method_basic_definition_p(klass, mid)
287 return FIXNUM_POSITIVE_P(num);
289 else if (RB_BIGNUM_TYPE_P(num)) {
290 return BIGNUM_POSITIVE_P(num);
292 rb_raise(rb_eTypeError,
"not an Integer");
299 return FIXNUM_NEGATIVE_P(num);
301 else if (RB_BIGNUM_TYPE_P(num)) {
302 return BIGNUM_NEGATIVE_P(num);
304 rb_raise(rb_eTypeError,
"not an Integer");
308rb_int_positive_p(VALUE num)
310 return int_pos_p(num);
314rb_int_negative_p(VALUE num)
316 return int_neg_p(num);
320rb_num_negative_p(VALUE num)
322 return rb_num_negative_int_p(num);
326num_funcall_op_0(VALUE x, VALUE arg,
int recursive)
332 rb_name_error(func,
"%"PRIsVALUE
".%"PRIsVALUE,
335 else if (name[0] && name[1] ==
'@' && !name[2]) {
336 rb_name_error(func,
"%c%"PRIsVALUE,
340 rb_name_error(func,
"%"PRIsVALUE
"%"PRIsVALUE,
348num_funcall0(VALUE x, ID func)
353NORETURN(
static void num_funcall_op_1_recursion(VALUE x, ID func, VALUE y));
356num_funcall_op_1_recursion(VALUE x, ID func, VALUE y)
360 rb_name_error(func,
"%"PRIsVALUE
".%"PRIsVALUE
"(%"PRIsVALUE
")",
364 rb_name_error(func,
"%"PRIsVALUE
"%"PRIsVALUE
"%"PRIsVALUE,
370num_funcall_op_1(VALUE y, VALUE arg,
int recursive)
372 ID func = (
ID)((VALUE *)arg)[0];
373 VALUE x = ((VALUE *)arg)[1];
375 num_funcall_op_1_recursion(x, func, y);
381num_funcall1(VALUE x, ID func, VALUE y)
384 args[0] = (
VALUE)func;
425num_coerce(VALUE x, VALUE y)
434NORETURN(
static void coerce_failed(VALUE x, VALUE y));
436coerce_failed(VALUE x, VALUE y)
444 rb_raise(rb_eTypeError,
"%"PRIsVALUE
" can't be coerced into %"PRIsVALUE,
449do_coerce(VALUE *x, VALUE *y,
int err)
454 coerce_failed(*x, *y);
458 if (!err &&
NIL_P(ary)) {
462 rb_raise(rb_eTypeError,
"coerce must return [x, y]");
473 do_coerce(&x, &y, TRUE);
480 if (do_coerce(&x, &y, FALSE))
486ensure_cmp(VALUE c, VALUE x, VALUE y)
495 VALUE x0 = x, y0 = y;
497 if (!do_coerce(&x, &y, FALSE)) {
501 return ensure_cmp(
rb_funcall(x, func, 1, y), x0, y0);
504NORETURN(
static VALUE num_sadded(VALUE x, VALUE name));
515num_sadded(VALUE x, VALUE name)
521 "can't define singleton method \"%"PRIsVALUE
"\" for %"PRIsVALUE,
541num_clone(
int argc, VALUE *argv, VALUE x)
543 return rb_immutable_obj_clone(argc, argv, x);
546# define num_clone rb_immutable_obj_clone
565# define num_dup num_uplus
597num_imaginary(VALUE num)
615 do_coerce(&zero, &num, TRUE);
617 return num_funcall1(zero,
'-', num);
634num_fdiv(VALUE x, VALUE y)
653num_div(VALUE x, VALUE y)
696num_modulo(VALUE x, VALUE y)
698 VALUE q = num_funcall1(x, id_div, y);
735num_remainder(VALUE x, VALUE y)
737 VALUE z = num_funcall1(x,
'%', y);
739 if ((!rb_equal(z,
INT2FIX(0))) &&
740 ((rb_num_negative_int_p(x) &&
741 rb_num_positive_int_p(y)) ||
742 (rb_num_positive_int_p(x) &&
743 rb_num_negative_int_p(y)))) {
783num_divmod(VALUE x, VALUE y)
805 if (rb_num_negative_int_p(num)) {
806 return num_funcall0(num, idUMinus);
825 return rb_equal(num,
INT2FIX(0));
832 return RBOOL(FIXNUM_ZERO_P(num));
834 assert(RB_BIGNUM_TYPE_P(num));
839rb_int_zero_p(VALUE num)
841 return int_zero_p(num);
863num_nonzero_p(VALUE num)
893 return num_funcall0(num, id_to_i);
905num_positive_p(VALUE num)
913 else if (RB_BIGNUM_TYPE_P(num)) {
915 return RBOOL(BIGNUM_POSITIVE_P(num) && !
rb_bigzero_p(num));
917 return rb_num_compare_with_zero(num, mid);
929num_negative_p(VALUE num)
931 return RBOOL(rb_num_negative_int_p(num));
1020#if SIZEOF_DOUBLE <= SIZEOF_VALUE
1021 flt->float_value = d;
1025 rb_float_value_type v;
1027 flt->float_value = u.v;
1058 enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
1059 enum {float_dig = DBL_DIG+1};
1060 char buf[float_dig + (decimal_mant + CHAR_BIT - 1) / CHAR_BIT + 10];
1064 int sign, decpt, digs;
1067 static const char minf[] =
"-Infinity";
1068 const int pos = (value > 0);
1071 else if (isnan(value))
1074 p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
1076 if ((digs = (
int)(e - p)) >= (
int)
sizeof(buf)) digs = (int)
sizeof(buf) - 1;
1077 memcpy(buf, p, digs);
1081 memmove(buf + decpt + 1, buf + decpt, digs - decpt);
1085 else if (decpt <= DBL_DIG) {
1092 memset(ptr,
'0', decpt - digs);
1093 ptr += decpt - digs;
1095 memcpy(ptr,
".0", 2);
1101 else if (decpt > -4) {
1107 memset(ptr += len,
'0', -decpt);
1108 memcpy(ptr -= decpt, buf, digs);
1117 memmove(buf + 2, buf + 1, digs - 1);
1147flo_coerce(VALUE x, VALUE y)
1152MJIT_FUNC_EXPORTED VALUE
1153rb_float_uminus(VALUE flt)
1173rb_float_plus(VALUE x, VALUE y)
1178 else if (RB_BIGNUM_TYPE_P(y)) {
1204rb_float_minus(VALUE x, VALUE y)
1209 else if (RB_BIGNUM_TYPE_P(y)) {
1234rb_float_mul(VALUE x, VALUE y)
1239 else if (RB_BIGNUM_TYPE_P(y)) {
1251double_div_double(
double x,
double y)
1253 if (LIKELY(y != 0.0)) {
1256 else if (x == 0.0) {
1260 double z = signbit(y) ? -1.0 : 1.0;
1261 return x * z * HUGE_VAL;
1265MJIT_FUNC_EXPORTED VALUE
1266rb_flo_div_flo(VALUE x, VALUE y)
1270 double ret = double_div_double(num, den);
1289rb_float_div(VALUE x, VALUE y)
1298 else if (RB_BIGNUM_TYPE_P(y)) {
1308 ret = double_div_double(num, den);
1329flo_quo(VALUE x, VALUE y)
1331 return num_funcall1(x,
'/', y);
1335flodivmod(
double x,
double y,
double *divp,
double *modp)
1341 if (modp) *modp = y;
1342 if (divp) *divp = y;
1346 if ((x == 0.0) || (isinf(y) && !isinf(x)))
1358 if (isinf(x) && !isinf(y))
1361 div = (x - mod) / y;
1362 if (modp && divp) div = round(div);
1368 if (modp) *modp = mod;
1369 if (divp) *divp = div;
1377MJIT_FUNC_EXPORTED
double
1378ruby_float_mod(
double x,
double y)
1381 flodivmod(x, y, 0, &mod);
1417flo_mod(VALUE x, VALUE y)
1424 else if (RB_BIGNUM_TYPE_P(y)) {
1472flo_divmod(VALUE x, VALUE y)
1474 double fy, div, mod;
1475 volatile VALUE a, b;
1480 else if (RB_BIGNUM_TYPE_P(y)) {
1511rb_float_pow(VALUE x, VALUE y)
1522 else if (RB_BIGNUM_TYPE_P(y)) {
1529 if (dx < 0 && dy != round(dy))
1530 return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
1560num_eql(VALUE x, VALUE y)
1564 if (RB_BIGNUM_TYPE_P(x)) {
1568 return rb_equal(x, y);
1582num_cmp(VALUE x, VALUE y)
1584 if (x == y)
return INT2FIX(0);
1589num_equal(VALUE x, VALUE y)
1592 if (x == y)
return Qtrue;
1593 result = num_funcall1(y, id_eq, x);
1594 return RBOOL(
RTEST(result));
1614MJIT_FUNC_EXPORTED VALUE
1615rb_float_equal(VALUE x, VALUE y)
1617 volatile double a, b;
1620 return rb_integer_float_eq(y, x);
1624#if MSC_VERSION_BEFORE(1300)
1625 if (isnan(b))
return Qfalse;
1629 return num_equal(x, y);
1632#if MSC_VERSION_BEFORE(1300)
1633 if (isnan(a))
return Qfalse;
1635 return RBOOL(a == b);
1638#define flo_eq rb_float_equal
1639static VALUE rb_dbl_hash(
double d);
1657rb_dbl_hash(
double d)
1659 return ST2FIX(rb_dbl_long_hash(d));
1665 if (isnan(a) || isnan(b))
return Qnil;
1666 if (a == b)
return INT2FIX(0);
1668 if (a < b)
return INT2FIX(-1);
1701flo_cmp(VALUE x, VALUE y)
1707 if (isnan(a))
return Qnil;
1709 VALUE rel = rb_integer_float_cmp(y, x);
1721 j = (a > 0.0) ? (j > 0 ? 0 : +1) : (j < 0 ? 0 : -1);
1724 if (a > 0.0)
return INT2FIX(1);
1732MJIT_FUNC_EXPORTED
int
1733rb_float_cmp(VALUE x, VALUE y)
1735 return NUM2INT(ensure_cmp(flo_cmp(x, y), x, y));
1754rb_float_gt(VALUE x, VALUE y)
1760 VALUE rel = rb_integer_float_cmp(y, x);
1767#if MSC_VERSION_BEFORE(1300)
1768 if (isnan(b))
return Qfalse;
1774#if MSC_VERSION_BEFORE(1300)
1775 if (isnan(a))
return Qfalse;
1777 return RBOOL(a > b);
1797flo_ge(VALUE x, VALUE y)
1803 VALUE rel = rb_integer_float_cmp(y, x);
1810#if MSC_VERSION_BEFORE(1300)
1811 if (isnan(b))
return Qfalse;
1817#if MSC_VERSION_BEFORE(1300)
1818 if (isnan(a))
return Qfalse;
1820 return RBOOL(a >= b);
1839flo_lt(VALUE x, VALUE y)
1845 VALUE rel = rb_integer_float_cmp(y, x);
1852#if MSC_VERSION_BEFORE(1300)
1853 if (isnan(b))
return Qfalse;
1859#if MSC_VERSION_BEFORE(1300)
1860 if (isnan(a))
return Qfalse;
1862 return RBOOL(a < b);
1882flo_le(VALUE x, VALUE y)
1888 VALUE rel = rb_integer_float_cmp(y, x);
1895#if MSC_VERSION_BEFORE(1300)
1896 if (isnan(b))
return Qfalse;
1902#if MSC_VERSION_BEFORE(1300)
1903 if (isnan(a))
return Qfalse;
1905 return RBOOL(a <= b);
1926MJIT_FUNC_EXPORTED VALUE
1927rb_float_eql(VALUE x, VALUE y)
1932#if MSC_VERSION_BEFORE(1300)
1933 if (isnan(a) || isnan(b))
return Qfalse;
1935 return RBOOL(a == b);
1940#define flo_eql rb_float_eql
1942MJIT_FUNC_EXPORTED VALUE
1943rb_float_abs(VALUE flt)
1962flo_is_nan_p(VALUE num)
1966 return RBOOL(isnan(value));
1993rb_flo_is_infinite_p(VALUE num)
1998 return INT2FIX( value < 0 ? -1 : 1 );
2023rb_flo_is_finite_p(VALUE num)
2027 return RBOOL(isfinite(value));
2031flo_nextafter(VALUE flo,
double value)
2035 y = nextafter(x, value);
2084flo_next_float(VALUE vx)
2086 return flo_nextafter(vx, HUGE_VAL);
2125flo_prev_float(VALUE vx)
2127 return flo_nextafter(vx, -HUGE_VAL);
2131rb_float_floor(VALUE num,
int ndigits)
2135 if (number == 0.0) {
2141 frexp(number, &binexp);
2142 if (float_round_overflow(ndigits, binexp))
return num;
2143 if (number > 0.0 && float_round_underflow(ndigits, binexp))
2145 f = pow(10, ndigits);
2146 mul = floor(number * f);
2147 res = (mul + 1) / f;
2153 num = dbl2ival(floor(number));
2154 if (ndigits < 0) num = rb_int_floor(num, ndigits);
2160flo_ndigits(
int argc, VALUE *argv)
2205flo_floor(
int argc, VALUE *argv, VALUE num)
2207 int ndigits = flo_ndigits(argc, argv);
2208 return rb_float_floor(num, ndigits);
2248flo_ceil(
int argc, VALUE *argv, VALUE num)
2250 int ndigits = flo_ndigits(argc, argv);
2251 return rb_float_ceil(num, ndigits);
2255rb_float_ceil(VALUE num,
int ndigits)
2260 if (number == 0.0) {
2265 frexp(number, &binexp);
2266 if (float_round_overflow(ndigits, binexp))
return num;
2267 if (number < 0.0 && float_round_underflow(ndigits, binexp))
2269 f = pow(10, ndigits);
2270 f = ceil(number * f) / f;
2274 num = dbl2ival(ceil(number));
2275 if (ndigits < 0) num = rb_int_ceil(num, ndigits);
2281int_round_zero_p(VALUE num,
int ndigits)
2287 bytes =
sizeof(long);
2289 else if (RB_BIGNUM_TYPE_P(num)) {
2290 bytes = rb_big_size(num);
2295 return (-0.415241 * ndigits - 0.125 > bytes);
2302 if ((z * y - x) * 2 == y) {
2311 return (x + y / 2) / y * y;
2317 return (x + y / 2 - 1) / y * y;
2321int_half_p_half_even(VALUE num, VALUE n, VALUE f)
2323 return (
int)rb_int_odd_p(rb_int_idiv(n, f));
2327int_half_p_half_up(VALUE num, VALUE n, VALUE f)
2329 return int_pos_p(num);
2333int_half_p_half_down(VALUE num, VALUE n, VALUE f)
2335 return int_neg_p(num);
2342rb_int_round(VALUE num,
int ndigits,
enum ruby_num_rounding_mode mode)
2346 if (int_round_zero_p(num, ndigits)) {
2350 f = int_pow(10, -ndigits);
2355 x = ROUND_CALL(mode, int_round, (x, y));
2363 h = rb_int_idiv(f,
INT2FIX(2));
2364 r = rb_int_modulo(num, f);
2365 n = rb_int_minus(num, r);
2366 r = rb_int_cmp(r, h);
2367 if (FIXNUM_POSITIVE_P(r) ||
2368 (FIXNUM_ZERO_P(r) && ROUND_CALL(mode, int_half_p, (num, n, f)))) {
2369 n = rb_int_plus(n, f);
2375rb_int_floor(VALUE num,
int ndigits)
2379 if (int_round_zero_p(num, ndigits))
2381 f = int_pow(10, -ndigits);
2385 if (neg) x = -x + y - 1;
2394 return rb_int_minus(num, rb_int_modulo(num, f));
2398rb_int_ceil(VALUE num,
int ndigits)
2402 if (int_round_zero_p(num, ndigits))
2404 f = int_pow(10, -ndigits);
2418 return rb_int_plus(num, rb_int_minus(f, rb_int_modulo(num, f)));
2422rb_int_truncate(VALUE num,
int ndigits)
2427 if (int_round_zero_p(num, ndigits))
2429 f = int_pow(10, -ndigits);
2442 m = rb_int_modulo(num, f);
2443 if (int_neg_p(num)) {
2444 return rb_int_plus(num, rb_int_minus(f, m));
2447 return rb_int_minus(num, m);
2507flo_round(
int argc, VALUE *argv, VALUE num)
2509 double number, f, x;
2512 enum ruby_num_rounding_mode mode;
2517 mode = rb_num_get_rounding_option(opt);
2519 if (number == 0.0) {
2523 return rb_int_round(flo_to_i(num), ndigits, mode);
2526 x = ROUND_CALL(mode, round, (number, 1.0));
2529 if (isfinite(number)) {
2531 frexp(number, &binexp);
2532 if (float_round_overflow(ndigits, binexp))
return num;
2533 if (float_round_underflow(ndigits, binexp))
return DBL2NUM(0);
2536 return rb_flo_round_by_rational(argc, argv, num);
2538 f = pow(10, ndigits);
2539 x = ROUND_CALL(mode, round, (number, f));
2546float_round_overflow(
int ndigits,
int binexp)
2548 enum {float_dig = DBL_DIG+2};
2567 if (ndigits >= float_dig - (binexp > 0 ? binexp / 4 : binexp / 3 - 1)) {
2574float_round_underflow(
int ndigits,
int binexp)
2576 if (ndigits < - (binexp > 0 ? binexp / 3 + 1 : binexp / 4)) {
2604 if (f > 0.0) f = floor(f);
2605 if (f < 0.0) f = ceil(f);
2646flo_truncate(
int argc, VALUE *argv, VALUE num)
2649 return flo_ceil(argc, argv, num);
2651 return flo_floor(argc, argv, num);
2666num_floor(
int argc, VALUE *argv, VALUE num)
2668 return flo_floor(argc, argv, rb_Float(num));
2683num_ceil(
int argc, VALUE *argv, VALUE num)
2685 return flo_ceil(argc, argv, rb_Float(num));
2700num_round(
int argc, VALUE* argv, VALUE num)
2702 return flo_round(argc, argv, rb_Float(num));
2717num_truncate(
int argc, VALUE *argv, VALUE num)
2719 return flo_truncate(argc, argv, rb_Float(num));
2723ruby_float_step_size(
double beg,
double end,
double unit,
int excl)
2725 const double epsilon = DBL_EPSILON;
2732 return unit > 0 ? beg <= end : beg >= end;
2734 n= (end - beg)/unit;
2735 err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
2736 if (err>0.5) err=0.5;
2743 d = +((n + 1) * unit) + beg;
2748 else if (beg > end) {
2756 d = +((n + 1) * unit) + beg;
2761 else if (beg > end) {
2770ruby_float_step(VALUE from, VALUE to, VALUE step,
int excl,
int allow_endless)
2775 double end = (allow_endless &&
NIL_P(to)) ? (unit < 0 ? -1 : 1)*HUGE_VAL :
NUM2DBL(to);
2776 double n = ruby_float_step_size(beg, end, unit, excl);
2783 else if (unit == 0) {
2789 for (i=0; i<n; i++) {
2790 double d = i*unit+beg;
2791 if (unit >= 0 ? end < d : d < end) d = end;
2801ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step,
int excl)
2826 if (isinf(n))
return DBL2NUM(n);
2834 case 0:
return DBL2NUM(HUGE_VAL);
2835 case -1: cmp =
'<';
break;
2847num_step_negative_p(VALUE num)
2857 else if (RB_BIGNUM_TYPE_P(num)) {
2859 return BIGNUM_NEGATIVE_P(num);
2864 coerce_failed(num,
INT2FIX(0));
2870num_step_extract_args(
int argc,
const VALUE *argv, VALUE *to, VALUE *step, VALUE *by)
2874 argc =
rb_scan_args(argc, argv,
"02:", to, step, &hash);
2881 if (values[0] !=
Qundef) {
2882 if (argc > 0)
rb_raise(rb_eArgError,
"to is given twice");
2885 if (values[1] !=
Qundef) {
2886 if (argc > 1)
rb_raise(rb_eArgError,
"step is given twice");
2895num_step_check_fix_args(
int argc, VALUE *to, VALUE *step, VALUE by,
int fix_nil,
int allow_zero_step)
2903 if (argc > 1 &&
NIL_P(*step)) {
2904 rb_raise(rb_eTypeError,
"step must be numeric");
2907 if (!allow_zero_step && rb_equal(*step,
INT2FIX(0))) {
2908 rb_raise(rb_eArgError,
"step can't be 0");
2913 desc = num_step_negative_p(*step);
2914 if (fix_nil &&
NIL_P(*to)) {
2921num_step_scan_args(
int argc,
const VALUE *argv, VALUE *to, VALUE *step,
int fix_nil,
int allow_zero_step)
2924 argc = num_step_extract_args(argc, argv, to, step, &by);
2925 return num_step_check_fix_args(argc, to, step, by, fix_nil, allow_zero_step);
2929num_step_size(VALUE from, VALUE args, VALUE eobj)
2935 num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
2937 return ruby_num_interval_step_size(from, to, step, FALSE);
3037num_step(
int argc, VALUE *argv, VALUE from)
3045 num_step_extract_args(argc, argv, &to, &step, &by);
3052 else if (rb_equal(step,
INT2FIX(0))) {
3053 rb_raise(rb_eArgError,
"step can't be 0");
3058 num_step_size, from, to, step, FALSE);
3064 desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
3065 if (rb_equal(step,
INT2FIX(0))) {
3070 inf = isinf(f) && (signbit(f) ? desc : !desc);
3086 for (; i >= end; i += diff)
3090 for (; i <= end; i += diff)
3095 else if (!ruby_float_step(from, to, step, FALSE, FALSE)) {
3103 ID cmp = desc ?
'<' :
'>';
3113out_of_range_float(
char (*pbuf)[24], VALUE val)
3115 char *
const buf = *pbuf;
3118 snprintf(buf,
sizeof(*pbuf),
"%-.10g",
RFLOAT_VALUE(val));
3119 if ((s = strchr(buf,
' ')) != 0) *s =
'\0';
3123#define FLOAT_OUT_OF_RANGE(val, type) do { \
3125 rb_raise(rb_eRangeError, "float %s out of range of "type, \
3126 out_of_range_float(&buf, (val))); \
3129#define LONG_MIN_MINUS_ONE ((double)LONG_MIN-1)
3130#define LONG_MAX_PLUS_ONE (2*(double)(LONG_MAX/2+1))
3131#define ULONG_MAX_PLUS_ONE (2*(double)(ULONG_MAX/2+1))
3132#define LONG_MIN_MINUS_ONE_IS_LESS_THAN(n) \
3133 (LONG_MIN_MINUS_ONE == (double)LONG_MIN ? \
3135 LONG_MIN_MINUS_ONE < (n))
3142 rb_raise(rb_eTypeError,
"no implicit conversion from nil to integer");
3149 && LONG_MIN_MINUS_ONE_IS_LESS_THAN(
RFLOAT_VALUE(val))) {
3153 FLOAT_OUT_OF_RANGE(val,
"integer");
3156 else if (RB_BIGNUM_TYPE_P(val)) {
3160 val = rb_to_int(val);
3166rb_num2ulong_internal(VALUE val,
int *wrap_p)
3170 rb_raise(rb_eTypeError,
"no implicit conversion from nil to integer");
3177 return (
unsigned long)l;
3181 if (d < ULONG_MAX_PLUS_ONE && LONG_MIN_MINUS_ONE_IS_LESS_THAN(d)) {
3183 *wrap_p = d <= -1.0;
3185 return (
unsigned long)d;
3186 return (
unsigned long)(long)d;
3189 FLOAT_OUT_OF_RANGE(val,
"integer");
3192 else if (RB_BIGNUM_TYPE_P(val)) {
3196 *wrap_p = BIGNUM_NEGATIVE_P(val);
3201 val = rb_to_int(val);
3209 return rb_num2ulong_internal(val, NULL);
3215 rb_raise(rb_eRangeError,
"integer %"PRIdVALUE
" too %s to convert to `int'",
3216 num, num < 0 ?
"small" :
"big");
3219#if SIZEOF_INT < SIZEOF_LONG
3223 if ((
long)(
int)num != num) {
3229check_uint(
unsigned long num,
int sign)
3233 if (num < (
unsigned long)INT_MIN)
3234 rb_raise(rb_eRangeError,
"integer %ld too small to convert to `unsigned int'", (
long)num);
3239 rb_raise(rb_eRangeError,
"integer %lu too big to convert to `unsigned int'", num);
3265 unsigned long num = rb_num2ulong_internal(val, &wrap);
3267 check_uint(num, wrap);
3281 check_uint(num, FIXNUM_NEGATIVE_P(val));
3310NORETURN(
static void rb_out_of_short(
SIGNED_VALUE num));
3314 rb_raise(rb_eRangeError,
"integer %"PRIdVALUE
" too %s to convert to `short'",
3315 num, num < 0 ?
"small" :
"big");
3319check_short(
long num)
3321 if ((
long)(
short)num != num) {
3322 rb_out_of_short(num);
3327check_ushort(
unsigned long num,
int sign)
3331 if (num < (
unsigned long)SHRT_MIN)
3332 rb_raise(rb_eRangeError,
"integer %ld too small to convert to `unsigned short'", (
long)num);
3336 if (USHRT_MAX < num)
3337 rb_raise(rb_eRangeError,
"integer %lu too big to convert to `unsigned short'", num);
3363 unsigned long num = rb_num2ulong_internal(val, &wrap);
3365 check_ushort(num, wrap);
3379 check_ushort(num, FIXNUM_NEGATIVE_P(val));
3392 rb_raise(rb_eRangeError,
"integer %ld out of range of fixnum", v);
3398#define LLONG_MIN_MINUS_ONE ((double)LLONG_MIN-1)
3399#define LLONG_MAX_PLUS_ONE (2*(double)(LLONG_MAX/2+1))
3400#define ULLONG_MAX_PLUS_ONE (2*(double)(ULLONG_MAX/2+1))
3402#define ULLONG_MAX ((unsigned LONG_LONG)LLONG_MAX*2+1)
3404#define LLONG_MIN_MINUS_ONE_IS_LESS_THAN(n) \
3405 (LLONG_MIN_MINUS_ONE == (double)LLONG_MIN ? \
3407 LLONG_MIN_MINUS_ONE < (n))
3413 rb_raise(rb_eTypeError,
"no implicit conversion from nil");
3420 if (d < LLONG_MAX_PLUS_ONE && (LLONG_MIN_MINUS_ONE_IS_LESS_THAN(d))) {
3424 FLOAT_OUT_OF_RANGE(val,
"long long");
3427 else if (RB_BIGNUM_TYPE_P(val)) {
3428 return rb_big2ll(val);
3431 rb_raise(rb_eTypeError,
"no implicit conversion from string");
3434 rb_raise(rb_eTypeError,
"no implicit conversion from boolean");
3437 val = rb_to_int(val);
3445 rb_raise(rb_eTypeError,
"no implicit conversion from nil");
3452 if (d < ULLONG_MAX_PLUS_ONE && LLONG_MIN_MINUS_ONE_IS_LESS_THAN(d)) {
3458 FLOAT_OUT_OF_RANGE(val,
"unsigned long long");
3461 else if (RB_BIGNUM_TYPE_P(val)) {
3462 return rb_big2ull(val);
3465 rb_raise(rb_eTypeError,
"no implicit conversion from string");
3468 rb_raise(rb_eTypeError,
"no implicit conversion from boolean");
3471 val = rb_to_int(val);
3574rb_int_odd_p(VALUE num)
3577 return RBOOL(num & 2);
3580 assert(RB_BIGNUM_TYPE_P(num));
3581 return rb_big_odd_p(num);
3586int_even_p(VALUE num)
3589 return RBOOL((num & 2) == 0);
3592 assert(RB_BIGNUM_TYPE_P(num));
3593 return rb_big_even_p(num);
3598rb_int_even_p(VALUE num)
3600 return int_even_p(num);
3627int_allbits_p(VALUE num, VALUE mask)
3629 mask = rb_to_int(mask);
3630 return rb_int_equal(rb_int_and(num, mask), mask);
3657int_anybits_p(VALUE num, VALUE mask)
3659 mask = rb_to_int(mask);
3660 return int_zero_p(rb_int_and(num, mask)) ?
Qfalse :
Qtrue;
3687int_nobits_p(VALUE num, VALUE mask)
3689 mask = rb_to_int(mask);
3690 return int_zero_p(rb_int_and(num, mask));
3708rb_int_succ(VALUE num)
3714 if (RB_BIGNUM_TYPE_P(num)) {
3717 return num_funcall1(num,
'+',
INT2FIX(1));
3720#define int_succ rb_int_succ
3736rb_int_pred(VALUE num)
3742 if (RB_BIGNUM_TYPE_P(num)) {
3745 return num_funcall1(num,
'-',
INT2FIX(1));
3748#define int_pred rb_int_pred
3756 case ONIGERR_INVALID_CODE_POINT_VALUE:
3759 case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE:
3761 rb_raise(rb_eRangeError,
"%u out of char range", code);
3792int_chr(
int argc, VALUE *argv, VALUE num)
3798 if (rb_num_to_uint(num, &i) == 0) {
3804 rb_raise(rb_eRangeError,
"bignum out of char range");
3812 rb_raise(rb_eRangeError,
"%u out of char range", i);
3826 rb_error_arity(argc, 0, 1);
3839fix_uminus(VALUE num)
3845rb_int_uminus(VALUE num)
3848 return fix_uminus(num);
3851 assert(RB_BIGNUM_TYPE_P(num));
3852 return rb_big_uminus(num);
3859 char buf[
SIZEOF_VALUE*CHAR_BIT + 1], *
const e = buf +
sizeof buf, *b = e;
3864 if (base < 2 || 36 < base) {
3865 rb_raise(rb_eArgError,
"invalid radix %d", base);
3867#if SIZEOF_LONG < SIZEOF_VOIDP
3868# if SIZEOF_VOIDP == SIZEOF_LONG_LONG
3869 if ((val >= 0 && (x & 0xFFFFFFFF00000000ull)) ||
3870 (val < 0 && (x & 0xFFFFFFFF00000000ull) != 0xFFFFFFFF00000000ull)) {
3871 rb_bug(
"Unnormalized Fixnum value %p", (
void *)x);
3882 u = 1 + (
unsigned long)(-(val + 1));
3889 *--b = ruby_digitmap[(int)(u % base)];
3890 }
while (u /= base);
3898static VALUE rb_fix_to_s_static[10];
3900MJIT_FUNC_EXPORTED VALUE
3904 if (i >= 0 && i < 10) {
3905 return rb_fix_to_s_static[i];
3931MJIT_FUNC_EXPORTED VALUE
3932rb_int_to_s(
int argc, VALUE *argv, VALUE x)
3940 return rb_int2str(x, base);
3944rb_int2str(VALUE x,
int base)
3949 else if (RB_BIGNUM_TYPE_P(x)) {
3953 return rb_any_to_s(x);
3957fix_plus(VALUE x, VALUE y)
3960 return rb_fix_plus_fix(x, y);
3962 else if (RB_BIGNUM_TYPE_P(y)) {
3977rb_fix_plus(VALUE x, VALUE y)
3979 return fix_plus(x, y);
3998rb_int_plus(VALUE x, VALUE y)
4001 return fix_plus(x, y);
4003 else if (RB_BIGNUM_TYPE_P(x)) {
4010fix_minus(VALUE x, VALUE y)
4013 return rb_fix_minus_fix(x, y);
4015 else if (RB_BIGNUM_TYPE_P(y)) {
4043rb_int_minus(VALUE x, VALUE y)
4046 return fix_minus(x, y);
4048 else if (RB_BIGNUM_TYPE_P(x)) {
4055#define SQRT_LONG_MAX HALF_LONG_MSB
4057#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
4060fix_mul(VALUE x, VALUE y)
4063 return rb_fix_mul_fix(x, y);
4065 else if (RB_BIGNUM_TYPE_P(y)) {
4098rb_int_mul(VALUE x, VALUE y)
4101 return fix_mul(x, y);
4103 else if (RB_BIGNUM_TYPE_P(x)) {
4110fix_fdiv_double(VALUE x, VALUE y)
4115 else if (RB_BIGNUM_TYPE_P(y)) {
4127rb_int_fdiv_double(VALUE x, VALUE y)
4130 VALUE gcd = rb_gcd(x, y);
4131 if (!FIXNUM_ZERO_P(gcd)) {
4132 x = rb_int_idiv(x, gcd);
4133 y = rb_int_idiv(y, gcd);
4137 return fix_fdiv_double(x, y);
4139 else if (RB_BIGNUM_TYPE_P(x)) {
4140 return rb_big_fdiv_double(x, y);
4164rb_int_fdiv(VALUE x, VALUE y)
4167 return DBL2NUM(rb_int_fdiv_double(x, y));
4173fix_divide(VALUE x, VALUE y, ID op)
4177 return rb_fix_div_fix(x, y);
4179 else if (RB_BIGNUM_TYPE_P(y)) {
4186 return rb_flo_div_flo(
DBL2NUM(d), y);
4191 v = fix_divide(x, y,
'/');
4192 return flo_floor(0, 0, v);
4198 return rb_rational_reciprocal(y);
4204fix_div(VALUE x, VALUE y)
4206 return fix_divide(x, y,
'/');
4229rb_int_div(VALUE x, VALUE y)
4232 return fix_div(x, y);
4234 else if (RB_BIGNUM_TYPE_P(x)) {
4241fix_idiv(VALUE x, VALUE y)
4243 return fix_divide(x, y, id_div);
4265rb_int_idiv(VALUE x, VALUE y)
4268 return fix_idiv(x, y);
4270 else if (RB_BIGNUM_TYPE_P(x)) {
4273 return num_div(x, y);
4277fix_mod(VALUE x, VALUE y)
4281 return rb_fix_mod_fix(x, y);
4283 else if (RB_BIGNUM_TYPE_P(y)) {
4326rb_int_modulo(VALUE x, VALUE y)
4329 return fix_mod(x, y);
4331 else if (RB_BIGNUM_TYPE_P(x)) {
4334 return num_modulo(x, y);
4361int_remainder(VALUE x, VALUE y)
4364 return num_remainder(x, y);
4366 else if (RB_BIGNUM_TYPE_P(x)) {
4367 return rb_big_remainder(x, y);
4373fix_divmod(VALUE x, VALUE y)
4378 rb_fix_divmod_fix(x, y, &div, &mod);
4381 else if (RB_BIGNUM_TYPE_P(y)) {
4388 volatile VALUE a, b;
4427rb_int_divmod(VALUE x, VALUE y)
4430 return fix_divmod(x, y);
4432 else if (RB_BIGNUM_TYPE_P(x)) {
4455int_pow(
long x,
unsigned long y)
4460 if (y == 0)
return INT2FIX(1);
4469 while (y % 2 == 0) {
4470 if (!FIT_SQRT_LONG(x)) {
4477 if (MUL_OVERFLOW_FIXNUM_P(x, z)) {
4498 return int_pow(x, y);
4502fix_pow_inverted(VALUE x, VALUE minusb)
4509 VALUE y = rb_int_pow(x, minusb);
4522fix_pow(VALUE x, VALUE y)
4529 if (a == 1)
return INT2FIX(1);
4530 if (a == -1)
return INT2FIX(b % 2 ? -1 : 1);
4531 if (b < 0)
return fix_pow_inverted(x, fix_uminus(y));
4532 if (b == 0)
return INT2FIX(1);
4533 if (b == 1)
return x;
4534 if (a == 0)
return INT2FIX(0);
4535 return int_pow(a, b);
4537 else if (RB_BIGNUM_TYPE_P(y)) {
4538 if (a == 1)
return INT2FIX(1);
4539 if (a == -1)
return INT2FIX(int_even_p(y) ? 1 : -1);
4540 if (BIGNUM_NEGATIVE_P(y))
return fix_pow_inverted(x, rb_big_uminus(y));
4541 if (a == 0)
return INT2FIX(0);
4547 if (dy == 0.0)
return DBL2NUM(1.0);
4549 return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0);
4551 if (a == 1)
return DBL2NUM(1.0);
4552 if (a < 0 && dy != round(dy))
4553 return rb_dbl_complex_new_polar_pi(pow(-(
double)a, dy), dy);
4554 return DBL2NUM(pow((
double)a, dy));
4577rb_int_pow(VALUE x, VALUE y)
4580 return fix_pow(x, y);
4582 else if (RB_BIGNUM_TYPE_P(x)) {
4589rb_num_pow(VALUE x, VALUE y)
4591 VALUE z = rb_int_pow(x, y);
4592 if (!
NIL_P(z))
return z;
4599 return rb_rational_pow(x, y);
4607fix_equal(VALUE x, VALUE y)
4609 if (x == y)
return Qtrue;
4611 else if (RB_BIGNUM_TYPE_P(y)) {
4615 return rb_integer_float_eq(x, y);
4618 return num_equal(x, y);
4638rb_int_equal(VALUE x, VALUE y)
4641 return fix_equal(x, y);
4643 else if (RB_BIGNUM_TYPE_P(x)) {
4650fix_cmp(VALUE x, VALUE y)
4652 if (x == y)
return INT2FIX(0);
4657 else if (RB_BIGNUM_TYPE_P(y)) {
4666 return rb_integer_float_cmp(x, y);
4700rb_int_cmp(VALUE x, VALUE y)
4703 return fix_cmp(x, y);
4705 else if (RB_BIGNUM_TYPE_P(x)) {
4714fix_gt(VALUE x, VALUE y)
4719 else if (RB_BIGNUM_TYPE_P(y)) {
4723 return RBOOL(rb_integer_float_cmp(x, y) ==
INT2FIX(1));
4747rb_int_gt(VALUE x, VALUE y)
4750 return fix_gt(x, y);
4752 else if (RB_BIGNUM_TYPE_P(x)) {
4753 return rb_big_gt(x, y);
4759fix_ge(VALUE x, VALUE y)
4764 else if (RB_BIGNUM_TYPE_P(y)) {
4768 VALUE rel = rb_integer_float_cmp(x, y);
4794rb_int_ge(VALUE x, VALUE y)
4797 return fix_ge(x, y);
4799 else if (RB_BIGNUM_TYPE_P(x)) {
4800 return rb_big_ge(x, y);
4806fix_lt(VALUE x, VALUE y)
4811 else if (RB_BIGNUM_TYPE_P(y)) {
4815 return RBOOL(rb_integer_float_cmp(x, y) ==
INT2FIX(-1));
4839int_lt(VALUE x, VALUE y)
4842 return fix_lt(x, y);
4844 else if (RB_BIGNUM_TYPE_P(x)) {
4845 return rb_big_lt(x, y);
4851fix_le(VALUE x, VALUE y)
4856 else if (RB_BIGNUM_TYPE_P(y)) {
4860 VALUE rel = rb_integer_float_cmp(x, y);
4886int_le(VALUE x, VALUE y)
4889 return fix_le(x, y);
4891 else if (RB_BIGNUM_TYPE_P(x)) {
4892 return rb_big_le(x, y);
4904rb_int_comp(VALUE num)
4907 return fix_comp(num);
4909 else if (RB_BIGNUM_TYPE_P(num)) {
4910 return rb_big_comp(num);
4916num_funcall_bit_1(VALUE y, VALUE arg,
int recursive)
4918 ID func = (
ID)((VALUE *)arg)[0];
4919 VALUE x = ((VALUE *)arg)[1];
4921 num_funcall_op_1_recursion(x, func, y);
4931 args[0] = (
VALUE)func;
4934 do_coerce(&args[1], &args[2], TRUE);
4936 args[2], args[1], (VALUE)args);
4939 coerce_failed(x, y);
4945fix_and(VALUE x, VALUE y)
4952 if (RB_BIGNUM_TYPE_P(y)) {
4975rb_int_and(VALUE x, VALUE y)
4978 return fix_and(x, y);
4980 else if (RB_BIGNUM_TYPE_P(x)) {
4987fix_or(VALUE x, VALUE y)
4994 if (RB_BIGNUM_TYPE_P(y)) {
5017int_or(VALUE x, VALUE y)
5020 return fix_or(x, y);
5022 else if (RB_BIGNUM_TYPE_P(x)) {
5029fix_xor(VALUE x, VALUE y)
5036 if (RB_BIGNUM_TYPE_P(y)) {
5059int_xor(VALUE x, VALUE y)
5062 return fix_xor(x, y);
5064 else if (RB_BIGNUM_TYPE_P(x)) {
5071rb_fix_lshift(VALUE x, VALUE y)
5076 if (!val)
return (rb_to_int(y),
INT2FIX(0));
5081 return fix_rshift(val, (
unsigned long)-width);
5082 return fix_lshift(val, width);
5086fix_lshift(
long val,
unsigned long width)
5088 if (width > (SIZEOF_LONG*CHAR_BIT-1)
5089 || ((
unsigned long)val)>>(SIZEOF_LONG*CHAR_BIT-1-width) > 0) {
5114rb_int_lshift(VALUE x, VALUE y)
5117 return rb_fix_lshift(x, y);
5119 else if (RB_BIGNUM_TYPE_P(x)) {
5126rb_fix_rshift(VALUE x, VALUE y)
5131 if (!val)
return (rb_to_int(y),
INT2FIX(0));
5135 if (i == 0)
return x;
5137 return fix_lshift(val, (
unsigned long)-i);
5138 return fix_rshift(val, i);
5142fix_rshift(
long val,
unsigned long i)
5144 if (i >=
sizeof(
long)*CHAR_BIT-1) {
5145 if (val < 0)
return INT2FIX(-1);
5148 val = RSHIFT(val, i);
5170rb_int_rshift(VALUE x, VALUE y)
5173 return rb_fix_rshift(x, y);
5175 else if (RB_BIGNUM_TYPE_P(x)) {
5181MJIT_FUNC_EXPORTED VALUE
5182rb_fix_aref(VALUE fix, VALUE idx)
5187 idx = rb_to_int(idx);
5191 if (!BIGNUM_SIGN(idx) || val >= 0)
5199 if (SIZEOF_LONG*CHAR_BIT-1 <= i) {
5200 if (val < 0)
return INT2FIX(1);
5216compare_indexes(VALUE a, VALUE b)
5226generate_mask(VALUE len)
5232int_aref1(VALUE num, VALUE arg)
5234 VALUE orig_num = num, beg, end;
5240 if (!
RTEST(num_negative_p(end))) {
5241 if (!excl) end = rb_int_plus(end,
INT2FIX(1));
5242 VALUE mask = generate_mask(end);
5243 if (
RTEST(int_zero_p(rb_int_and(num, mask)))) {
5247 rb_raise(rb_eArgError,
"The beginless range for Integer#[] results in infinity");
5254 num = rb_int_rshift(num, beg);
5256 int cmp = compare_indexes(beg, end);
5257 if (!
NIL_P(end) && cmp < 0) {
5258 VALUE len = rb_int_minus(end, beg);
5259 if (!excl) len = rb_int_plus(len,
INT2FIX(1));
5260 VALUE mask = generate_mask(len);
5261 num = rb_int_and(num, mask);
5263 else if (cmp == 0) {
5274 return rb_fix_aref(num, arg);
5276 else if (RB_BIGNUM_TYPE_P(num)) {
5277 return rb_big_aref(num, arg);
5283int_aref2(VALUE num, VALUE beg, VALUE len)
5285 num = rb_int_rshift(num, beg);
5286 VALUE mask = generate_mask(len);
5287 num = rb_int_and(num, mask);
5331int_aref(
int const argc, VALUE *
const argv, VALUE
const num)
5335 return int_aref2(num, argv[0], argv[1]);
5337 return int_aref1(num, argv[0]);
5367 else if (RB_BIGNUM_TYPE_P(num)) {
5388rb_int_abs(VALUE num)
5391 return fix_abs(num);
5393 else if (RB_BIGNUM_TYPE_P(num)) {
5394 return rb_big_abs(num);
5405MJIT_FUNC_EXPORTED VALUE
5406rb_int_size(VALUE num)
5409 return fix_size(num);
5411 else if (RB_BIGNUM_TYPE_P(num)) {
5412 return rb_big_size_m(num);
5418rb_fix_bit_length(VALUE fix)
5427rb_int_bit_length(VALUE num)
5430 return rb_fix_bit_length(num);
5432 else if (RB_BIGNUM_TYPE_P(num)) {
5433 return rb_big_bit_length(num);
5439rb_fix_digits(VALUE fix,
long base)
5447 rb_raise(rb_eArgError,
"invalid radix %ld", base);
5463rb_int_digits_bigbase(VALUE num, VALUE base)
5465 VALUE digits, bases;
5467 assert(!rb_num_negative_p(num));
5469 if (RB_BIGNUM_TYPE_P(base))
5474 else if (RB_BIGNUM_TYPE_P(base) && BIGNUM_NEGATIVE_P(base))
5475 rb_raise(rb_eArgError,
"negative radix");
5478 return rb_fix_digits(num,
FIX2LONG(base));
5483 if (int_lt(rb_int_div(rb_int_bit_length(num), rb_int_bit_length(base)),
INT2FIX(50))) {
5486 VALUE qr = rb_int_divmod(num, base);
5494 for (VALUE b = base; int_lt(b, num) ==
Qtrue; b = rb_int_mul(b, b)) {
5501 for(i = last_idx; i >= 0; i--) {
5503 VALUE divmod = rb_int_divmod(n, b);
5531rb_int_digits(
int argc, VALUE *argv, VALUE num)
5536 if (rb_num_negative_p(num))
5540 base_value = rb_to_int(argv[0]);
5542 rb_raise(rb_eTypeError,
"wrong argument type %s (expected Integer)",
5544 if (RB_BIGNUM_TYPE_P(base_value))
5545 return rb_int_digits_bigbase(num, base_value);
5549 rb_raise(rb_eArgError,
"negative radix");
5551 rb_raise(rb_eArgError,
"invalid radix %ld", base);
5557 return rb_fix_digits(num, base);
5558 else if (RB_BIGNUM_TYPE_P(num))
5559 return rb_int_digits_bigbase(num,
LONG2FIX(base));
5565int_upto_size(VALUE from, VALUE args, VALUE eobj)
5591int_upto(VALUE from, VALUE to)
5598 for (i =
FIX2LONG(from); i <= end; i++) {
5609 ensure_cmp(c, i, to);
5615int_downto_size(VALUE from, VALUE args, VALUE eobj)
5641int_downto(VALUE from, VALUE to)
5648 for (i=
FIX2LONG(from); i >= end; i--) {
5665int_dotimes_size(VALUE num, VALUE args, VALUE eobj)
5692int_dotimes(VALUE num)
5700 for (i=0; i<end; i++) {
5708 if (!
RTEST(int_le(i, num)))
break;
5710 i = rb_int_plus(i,
INT2FIX(1));
5766int_round(
int argc, VALUE* argv, VALUE num)
5772 if (!
rb_scan_args(argc, argv,
"01:", &nd, &opt))
return num;
5774 mode = rb_num_get_rounding_option(opt);
5778 return rb_int_round(num, ndigits, mode);
5806int_floor(
int argc, VALUE* argv, VALUE num)
5815 return rb_int_floor(num, ndigits);
5843int_ceil(
int argc, VALUE* argv, VALUE num)
5852 return rb_int_ceil(num, ndigits);
5879int_truncate(
int argc, VALUE* argv, VALUE num)
5888 return rb_int_truncate(num, ndigits);
5891#define DEFINE_INT_SQRT(rettype, prefix, argtype) \
5893prefix##_isqrt(argtype n) \
5895 if (!argtype##_IN_DOUBLE_P(n)) { \
5896 unsigned int b = bit_length(n); \
5898 rettype x = (rettype)(n >> (b/2+1)); \
5899 x |= ((rettype)1LU << (b-1)/2); \
5900 while ((t = n/x) < (argtype)x) x = (rettype)((x + t) >> 1); \
5903 return (rettype)sqrt(argtype##_TO_DOUBLE(n)); \
5906#if SIZEOF_LONG*CHAR_BIT > DBL_MANT_DIG
5907# define RB_ULONG_IN_DOUBLE_P(n) ((n) < (1UL << DBL_MANT_DIG))
5909# define RB_ULONG_IN_DOUBLE_P(n) 1
5911#define RB_ULONG_TO_DOUBLE(n) (double)(n)
5912#define RB_ULONG unsigned long
5913DEFINE_INT_SQRT(
unsigned long, rb_ulong, RB_ULONG)
5915#if 2*SIZEOF_BDIGIT > SIZEOF_LONG
5916# if 2*SIZEOF_BDIGIT*CHAR_BIT > DBL_MANT_DIG
5917# define BDIGIT_DBL_IN_DOUBLE_P(n) ((n) < ((BDIGIT_DBL)1UL << DBL_MANT_DIG))
5919# define BDIGIT_DBL_IN_DOUBLE_P(n) 1
5921# ifdef ULL_TO_DOUBLE
5922# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
5924# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
5926DEFINE_INT_SQRT(BDIGIT, rb_bdigit_dbl, BDIGIT_DBL)
5929#define domain_error(msg) \
5930 rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
5965rb_int_s_isqrt(VALUE
self, VALUE num)
5967 unsigned long n, sq;
5968 num = rb_to_int(num);
5970 if (FIXNUM_NEGATIVE_P(num)) {
5971 domain_error(
"isqrt");
5974 sq = rb_ulong_isqrt(n);
5980 domain_error(
"isqrt");
5982 biglen = BIGNUM_LEN(num);
5983 if (biglen == 0)
return INT2FIX(0);
5984#if SIZEOF_BDIGIT <= SIZEOF_LONG
5987 n = BIGNUM_DIGITS(num)[0];
5988 sq = rb_ulong_isqrt(n);
5992 return rb_big_isqrt(num);
5998int_s_try_convert(VALUE
self, VALUE num)
6000 return rb_check_integer_type(num);
6281 rb_fix_to_s_static[0] = rb_fstring_literal(
"0");
6282 rb_fix_to_s_static[1] = rb_fstring_literal(
"1");
6283 rb_fix_to_s_static[2] = rb_fstring_literal(
"2");
6284 rb_fix_to_s_static[3] = rb_fstring_literal(
"3");
6285 rb_fix_to_s_static[4] = rb_fstring_literal(
"4");
6286 rb_fix_to_s_static[5] = rb_fstring_literal(
"5");
6287 rb_fix_to_s_static[6] = rb_fstring_literal(
"6");
6288 rb_fix_to_s_static[7] = rb_fstring_literal(
"7");
6289 rb_fix_to_s_static[8] = rb_fstring_literal(
"8");
6290 rb_fix_to_s_static[9] = rb_fstring_literal(
"9");
6291 for(
int i = 0; i < 10; i++) {
6422#undef rb_float_value
6426 return rb_float_value_inline(v);
6433 return rb_float_new_inline(d);
6436#include "numeric.rbinc"
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
double rb_float_value(VALUE num)
Extracts its double value from an instance of rb_cFloat.
VALUE rb_float_new_in_heap(double d)
Identical to rb_float_new(), except it does not generate Flonums.
VALUE rb_float_new(double d)
Converts a C's double into an instance of rb_cFloat.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a method.
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
#define T_COMPLEX
Old name of RUBY_T_COMPLEX.
#define TYPE(_)
Old name of rb_type.
#define NEWOBJ_OF
Old name of RB_NEWOBJ_OF.
#define RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
#define NUM2LL
Old name of RB_NUM2LL.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define T_STRING
Old name of RUBY_T_STRING.
#define xfree
Old name of ruby_xfree.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define T_FLOAT
Old name of RUBY_T_FLOAT.
#define ID2SYM
Old name of RB_ID2SYM.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define ULONG2NUM
Old name of RB_ULONG2NUM.
#define T_FIXNUM
Old name of RUBY_T_FIXNUM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define FIXNUM_FLAG
Old name of RUBY_FIXNUM_FLAG.
#define CLASS_OF
Old name of rb_class_of.
#define FIXABLE
Old name of RB_FIXABLE.
#define LONG2FIX
Old name of RB_INT2FIX.
#define FIX2INT
Old name of RB_FIX2INT.
#define FIX2ULONG
Old name of RB_FIX2ULONG.
#define T_TRUE
Old name of RUBY_T_TRUE.
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
#define NUM2DBL
Old name of rb_num2dbl.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define rb_usascii_str_new2
Old name of rb_usascii_str_new_cstr.
#define T_FALSE
Old name of RUBY_T_FALSE.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define NUM2INT
Old name of RB_NUM2INT.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define NUM2ULL
Old name of RB_NUM2ULL.
#define FL_WB_PROTECTED
Old name of RUBY_FL_WB_PROTECTED.
#define POSFIXABLE
Old name of RB_POSFIXABLE.
#define DBL2NUM
Old name of rb_float_new.
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define ISALNUM
Old name of rb_isalnum.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
VALUE rb_eZeroDivError
ZeroDivisionError exception.
VALUE rb_eFloatDomainError
FloatDomainError exception.
VALUE rb_eMathDomainError
Math::DomainError exception.
VALUE rb_cInteger
Module class.
VALUE rb_cNumeric
Numeric class.
VALUE rb_mComparable
Comparable module.
VALUE rb_cFloat
Float class.
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
Queries the number of bytes of the character at the passed pointer.
rb_encoding * rb_ascii8bit_encoding(void)
Queries the encoding that represents ASCII-8BIT a.k.a.
int rb_enc_codelen(int code, rb_encoding *enc)
Queries the number of bytes requested to represent the passed code point using the passed encoding.
rb_encoding * rb_to_encoding(VALUE obj)
Identical to rb_find_encoding(), except it raises an exception instead of returning NULL.
static const char * rb_enc_name(rb_encoding *enc)
Queries the (canonical) name of the passed encoding.
rb_encoding * rb_default_internal_encoding(void)
Queries the "default internal" encoding.
static int rb_enc_mbcput(unsigned int c, void *buf, rb_encoding *enc)
Identical to rb_enc_uint_chr(), except it writes back to the passed buffer instead of allocating one.
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
Encodes the passed code point into a series of bytes.
VALUE rb_enc_str_new(const char *ptr, long len, rb_encoding *enc)
Identical to rb_enc_str_new(), except it additionally takes an encoding.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
void rb_gc_register_mark_object(VALUE object)
Inform the garbage collector that object is a live Ruby object that should not be moved.
Defines RBIMPL_HAS_BUILTIN.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_pop(VALUE ary)
Destructively deletes an element from the end of the passed array and returns what was deleted.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_ary_new_from_args(long n,...)
Constructs an array from the passed objects.
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
VALUE rb_big_lshift(VALUE x, VALUE y)
Performs shift left.
VALUE rb_big_and(VALUE x, VALUE y)
Performs bitwise and of the passed two objects.
VALUE rb_big_or(VALUE x, VALUE y)
Performs bitwise or of the passed two objects.
VALUE rb_big_minus(VALUE x, VALUE y)
Performs subtraction of the passed two objects.
VALUE rb_big_modulo(VALUE x, VALUE y)
Performs modulo of the passed two objects.
VALUE rb_big_pow(VALUE x, VALUE y)
Raises x to the powerof y.
int rb_bigzero_p(VALUE x)
Queries if the passed bignum instance is a "bigzro".
VALUE rb_big_plus(VALUE x, VALUE y)
Performs addition of the passed two objects.
size_t rb_absint_size(VALUE val, int *nlz_bits_ret)
Calculates the number of bytes needed to represent the absolute value of the passed integer.
unsigned long rb_big2ulong(VALUE x)
Converts a bignum into C's unsigned long.
VALUE rb_big_idiv(VALUE x, VALUE y)
Performs "integer division".
VALUE rb_big2str(VALUE x, int base)
Generates a place-value representation of the passed integer.
VALUE rb_big_cmp(VALUE lhs, VALUE rhs)
Compares the passed two bignums.
VALUE rb_dbl2big(double d)
Converts a C's double into a bignum.
VALUE rb_big_mul(VALUE x, VALUE y)
Performs multiplication of the passed two objects.
VALUE rb_big_eql(VALUE lhs, VALUE rhs)
Equality, in terms of eql?.
VALUE rb_big_divmod(VALUE x, VALUE y)
Performs "divmod" operation.
VALUE rb_big_xor(VALUE x, VALUE y)
Performs exclusive or of the passed two objects.
VALUE rb_big_div(VALUE x, VALUE y)
Performs division of the passed two objects.
VALUE rb_big_norm(VALUE x)
Normalises the passed bignum.
VALUE rb_big_rshift(VALUE x, VALUE y)
Performs shift right.
double rb_big2dbl(VALUE x)
Converts a bignum into C's double.
long rb_big2long(VALUE x)
Converts a bignum into C's long.
VALUE rb_big_eq(VALUE lhs, VALUE rhs)
Equality, in terms of ==.
int rb_cmpint(VALUE val, VALUE a, VALUE b)
Canonicalises the passed val, which is the return value of a <=> b, into C's {-1, 0,...
void rb_cmperr(VALUE a, VALUE b)
Raises "comparison failed" error.
VALUE rb_complex_new(VALUE real, VALUE imag)
Constructs a Complex, by first multiplying the imaginary part with 1i then adds it to the real part.
VALUE rb_complex_plus(VALUE x, VALUE y)
Performs addition of the passed two objects.
VALUE rb_complex_mul(VALUE x, VALUE y)
Performs multiplication of the passed two objects.
VALUE rb_complex_pow(VALUE base, VALUE exp)
Performs exponentiation of the passed two objects.
#define SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This is an implementation detail of RETURN_SIZED_ENUMERATOR().
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
ID rb_frame_this_func(void)
Queries the name of the Ruby level method that is calling this function.
void rb_num_zerodiv(void)
Just always raises an exception.
VALUE rb_num2fix(VALUE val)
Converts a numeric value into a Fixnum.
VALUE rb_fix2str(VALUE val, int base)
Generates a place-value representation of the given Fixnum, with given radix.
VALUE rb_int_positive_pow(long x, unsigned long y)
Raises the passed x to the power of y.
VALUE rb_dbl_cmp(double lhs, double rhs)
Compares two doubles.
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op)
This one is optimised for bitwise operations, but the API is identical to rb_num_coerce_bin().
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_cmp(), except for return values.
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_bin(), except for return values.
VALUE rb_num_coerce_bin(VALUE lhs, VALUE rhs, ID op)
Coerced binary operation.
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Deconstructs a range into its components.
VALUE rb_rational_raw(VALUE num, VALUE den)
Identical to rb_rational_new(), except it skips argument validations.
int rb_memcicmp(const void *s1, const void *s2, long n)
Identical to st_locale_insensitive_strcasecmp(), except it is timing safe and returns something diffe...
VALUE rb_str_cat(VALUE dst, const char *src, long srclen)
Destructively appends the passed contents to the string.
VALUE rb_usascii_str_new(const char *ptr, long len)
Identical to rb_str_new(), except it generates a string of "US ASCII" encoding.
VALUE rb_usascii_str_new_cstr(const char *ptr)
Identical to rb_str_new_cstr(), except it generates a string of "US ASCII" encoding.
void rb_must_asciicompat(VALUE obj)
Asserts that the given string's encoding is (Ruby's definition of) ASCII compatible.
VALUE rb_str_new(const char *ptr, long len)
Allocates an instance of rb_cString.
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
VALUE rb_str_resize(VALUE str, long len)
Overwrites the length of the string.
VALUE rb_exec_recursive(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
"Recursion" API entry point.
VALUE rb_exec_recursive_paired(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h)
Identical to rb_exec_recursive(), except it checks for the recursion on the ordered pair of { g,...
void rb_undef_alloc_func(VALUE klass)
Deletes the allocator function of a class.
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it returns RUBY_Qundef instead of raising rb_eNoMethodError.
void rb_remove_method_id(VALUE klass, ID mid)
Identical to rb_remove_method(), except it accepts the method name as ID.
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
VALUE rb_sym2str(VALUE id)
Identical to rb_id2str(), except it takes an instance of rb_cSymbol rather than an ID.
ID rb_to_id(VALUE str)
Identical to rb_intern(), except it takes an instance of rb_cString.
const char * rb_id2name(ID id)
Retrieves the name mapped to the given id.
VALUE rb_id2str(ID id)
Identical to rb_id2name(), except it returns a Ruby's String instead of C's.
void rb_deprecate_constant(VALUE mod, const char *name)
Asserts that the given constant is deprecated.
void rb_define_const(VALUE klass, const char *name, VALUE val)
Defines a Ruby level constant under a namespace.
unsigned long rb_num2uint(VALUE num)
Converts an instance of rb_cNumeric into C's unsigned long.
long rb_fix2int(VALUE num)
Identical to rb_num2int().
long rb_num2int(VALUE num)
Converts an instance of rb_cNumeric into C's long.
unsigned long rb_fix2uint(VALUE num)
Identical to rb_num2uint().
VALUE rb_str_catf(VALUE dst, const char *fmt,...)
Identical to rb_sprintf(), except it renders the output to the specified object rather than creating ...
LONG_LONG rb_num2ll(VALUE num)
Converts an instance of rb_cNumeric into C's long long.
unsigned LONG_LONG rb_num2ull(VALUE num)
Converts an instance of rb_cNumeric into C's unsigned long long.
VALUE rb_int2big(intptr_t i)
Converts a C's intptr_t into an instance of rb_cInteger.
VALUE rb_yield(VALUE val)
Yields the block.
#define RB_FIX2ULONG
Just another name of rb_fix2ulong.
void rb_out_of_int(SIGNED_VALUE num)
This is an utility function to raise an rb_eRangeError.
long rb_num2long(VALUE num)
Converts an instance of rb_cNumeric into C's long.
unsigned long rb_num2ulong(VALUE num)
Converts an instance of rb_cNumeric into C's unsigned long.
#define RARRAY_LEN
Just another name of rb_array_len.
static int RARRAY_LENINT(VALUE ary)
Identical to rb_array_len(), except it differs for the return type.
#define RARRAY_AREF(a, i)
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
static bool RBIGNUM_NEGATIVE_P(VALUE b)
Checks if the bignum is negative.
#define RGENGC_WB_PROTECTED_FLOAT
This is a compile-time flag to enable/disable write barrier for struct RFloat.
static char * RSTRING_END(VALUE str)
Queries the end of the contents pointer of the string.
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
short rb_num2short(VALUE num)
Converts an instance of rb_cNumeric into C's short.
unsigned short rb_num2ushort(VALUE num)
Converts an instance of rb_cNumeric into C's unsigned short.
short rb_fix2short(VALUE num)
Identical to rb_num2short().
unsigned short rb_fix2ushort(VALUE num)
Identical to rb_num2ushort().
#define RTEST
This is an old name of RB_TEST.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_FLOAT_TYPE_P(VALUE obj)
Queries if the object is an instance of rb_cFloat.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.