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/error.h"
34#include "internal/gc.h"
35#include "internal/hash.h"
36#include "internal/numeric.h"
37#include "internal/object.h"
38#include "internal/rational.h"
39#include "internal/string.h"
40#include "internal/util.h"
41#include "internal/variable.h"
52#define DBL_MIN 2.2250738585072014e-308
55#define DBL_MAX 1.7976931348623157e+308
58#define DBL_MIN_EXP (-1021)
61#define DBL_MAX_EXP 1024
64#define DBL_MIN_10_EXP (-307)
67#define DBL_MAX_10_EXP 308
73#define DBL_MANT_DIG 53
76#define DBL_EPSILON 2.2204460492503131e-16
79#define ACCURATE_POW10(ndigits) ((ndigits) < DBL_DIG)
81#ifndef USE_RB_INFINITY
82#elif !defined(WORDS_BIGENDIAN)
89#elif !defined(WORDS_BIGENDIAN)
103 x = f + (x - f >= 0.5);
107 x = f - (f - x >= 0.5);
114round_half_up(
double x,
double s)
116 double f, xs = x * s;
119 if (s == 1.0)
return f;
121 if ((
double)((f + 0.5) / s) <= x) f += 1;
125 if ((
double)((f - 0.5) / s) >= x) f -= 1;
132round_half_down(
double x,
double s)
134 double f, xs = x * s;
138 if ((
double)((f - 0.5) / s) >= x) f -= 1;
142 if ((
double)((f + 0.5) / s) <= x) f += 1;
149round_half_even(
double x,
double s)
151 double u, v, us, vs, f, d, uf;
163 else if (d == 0.5 || ((
double)((uf + 0.5) / s) <= x))
175 else if (d == 0.5 || ((
double)((uf - 0.5) / s) >= x))
184static VALUE fix_lshift(
long,
unsigned long);
185static VALUE fix_rshift(
long,
unsigned long);
186static VALUE int_pow(
long x,
unsigned long y);
187static VALUE rb_int_floor(
VALUE num,
int ndigits);
188static VALUE rb_int_ceil(
VALUE num,
int ndigits);
190static int float_round_overflow(
int ndigits,
int binexp);
191static int float_round_underflow(
int ndigits,
int binexp);
195#define id_divmod idDivmod
196#define id_to_i idTo_i
207static ID id_to, id_by;
215enum ruby_num_rounding_mode
216rb_num_get_rounding_option(
VALUE opts)
218 static ID round_kwds[1];
224 if (!round_kwds[0]) {
227 if (!
rb_get_kwargs(opts, round_kwds, 0, 1, &rounding))
goto noopt;
231 else if (
NIL_P(rounding)) {
236 if (
NIL_P(str))
goto invalid;
239 s = RSTRING_PTR(str);
240 switch (RSTRING_LEN(str)) {
242 if (rb_memcicmp(s,
"up", 2) == 0)
243 return RUBY_NUM_ROUND_HALF_UP;
246 if (rb_memcicmp(s,
"even", 4) == 0)
247 return RUBY_NUM_ROUND_HALF_EVEN;
248 if (strncasecmp(s,
"down", 4) == 0)
249 return RUBY_NUM_ROUND_HALF_DOWN;
253 rb_raise(rb_eArgError,
"invalid rounding mode: % "PRIsVALUE, rounding);
256 return RUBY_NUM_ROUND_DEFAULT;
261rb_num_to_uint(
VALUE val,
unsigned int *ret)
264#define NUMERR_NEGATIVE 2
265#define NUMERR_TOOLARGE 3
268#if SIZEOF_INT < SIZEOF_LONG
269 if (v > (
long)UINT_MAX)
return NUMERR_TOOLARGE;
271 if (v < 0)
return NUMERR_NEGATIVE;
272 *ret = (
unsigned int)v;
276 if (RB_BIGNUM_TYPE_P(val)) {
277 if (BIGNUM_NEGATIVE_P(val))
return NUMERR_NEGATIVE;
278#if SIZEOF_INT < SIZEOF_LONG
280 return NUMERR_TOOLARGE;
283 if (rb_absint_size(val, NULL) >
sizeof(int))
return NUMERR_TOOLARGE;
284 *ret = (
unsigned int)rb_big2ulong((
VALUE)val);
291#define method_basic_p(klass) rb_method_basic_definition_p(klass, mid)
297 return FIXNUM_POSITIVE_P(num);
299 else if (RB_BIGNUM_TYPE_P(num)) {
300 return BIGNUM_POSITIVE_P(num);
309 return FIXNUM_NEGATIVE_P(num);
311 else if (RB_BIGNUM_TYPE_P(num)) {
312 return BIGNUM_NEGATIVE_P(num);
318rb_int_positive_p(
VALUE num)
320 return int_pos_p(num);
324rb_int_negative_p(
VALUE num)
326 return int_neg_p(num);
330rb_num_negative_p(
VALUE num)
332 return rb_num_negative_int_p(num);
336num_funcall_op_0(
VALUE x,
VALUE arg,
int recursive)
340 const char *name = rb_id2name(func);
345 else if (name[0] && name[1] ==
'@' && !name[2]) {
363NORETURN(
static void num_funcall_op_1_recursion(
VALUE x,
ID func,
VALUE y));
368 const char *name = rb_id2name(func);
370 rb_name_error(func,
"%"PRIsVALUE
".%"PRIsVALUE
"(%"PRIsVALUE
")",
380num_funcall_op_1(
VALUE y,
VALUE arg,
int recursive)
385 num_funcall_op_1_recursion(x, func, y);
394 args[0] = (
VALUE)func;
444NORETURN(
static void coerce_failed(
VALUE x,
VALUE y));
454 rb_raise(
rb_eTypeError,
"%"PRIsVALUE
" can't be coerced into %"PRIsVALUE,
464 coerce_failed(*x, *y);
468 if (!err &&
NIL_P(ary)) {
483 do_coerce(&x, &y, TRUE);
490 if (do_coerce(&x, &y, FALSE))
498 if (
NIL_P(c)) rb_cmperr_reason(x, y,
"comparator returned nil");
505 VALUE x0 = x, y0 = y;
507 if (!do_coerce(&x, &y, FALSE)) {
508 rb_cmperr_reason(x0, y0,
"coercion was not possible");
511 return ensure_cmp(
rb_funcall(x, func, 1, y), x0, y0);
531 "can't define singleton method \"%"PRIsVALUE
"\" for %"PRIsVALUE,
553 return rb_immutable_obj_clone(argc, argv, x);
556# define num_clone rb_immutable_obj_clone
574num_imaginary(
VALUE num)
576 return rb_complex_new(
INT2FIX(0), num);
592 do_coerce(&zero, &num, TRUE);
594 return num_funcall1(zero,
'-', num);
633 return rb_funcall(num_funcall1(x,
'/', y), rb_intern(
"floor"), 0);
673 VALUE q = num_funcall1(x, id_div, y);
713 do_coerce(&x, &y, TRUE);
715 VALUE z = num_funcall1(x,
'%', y);
718 ((rb_num_negative_int_p(x) &&
719 rb_num_positive_int_p(y)) ||
720 (rb_num_positive_int_p(x) &&
721 rb_num_negative_int_p(y)))) {
781 if (rb_num_negative_int_p(num)) {
782 return num_funcall0(num, idUMinus);
808 return FIXNUM_ZERO_P(num);
811 return rb_bigzero_p(num);
815rb_int_zero_p(
VALUE num)
817 return RBOOL(int_zero_p(num));
841num_nonzero_p(
VALUE num)
843 if (
RTEST(num_funcall0(num, rb_intern(
"zero?")))) {
872 return num_funcall0(num, id_to_i);
884num_positive_p(
VALUE num)
892 else if (RB_BIGNUM_TYPE_P(num)) {
894 return RBOOL(BIGNUM_POSITIVE_P(num) && !rb_bigzero_p(num));
896 return rb_num_compare_with_zero(num, mid);
908num_negative_p(
VALUE num)
910 return RBOOL(rb_num_negative_int_p(num));
918#if SIZEOF_DOUBLE <= SIZEOF_VALUE
919 flt->float_value = d;
923 rb_float_value_type v;
925 flt->float_value = u.v;
955 enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
956 enum {float_dig = DBL_DIG+1};
957 char buf[float_dig + roomof(decimal_mant, CHAR_BIT) + 10];
961 int sign, decpt, digs;
964 static const char minf[] =
"-Infinity";
965 const int pos = (value > 0);
968 else if (isnan(value))
971 p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
973 if ((digs = (
int)(e - p)) >= (
int)
sizeof(buf)) digs = (int)
sizeof(buf) - 1;
974 memcpy(buf, p, digs);
978 memmove(buf + decpt + 1, buf + decpt, digs - decpt);
982 else if (decpt <= DBL_DIG) {
986 rb_str_resize(s, (
len = RSTRING_LEN(s)) + decpt - digs + 2);
987 ptr = RSTRING_PTR(s) +
len;
989 memset(ptr,
'0', decpt - digs);
992 memcpy(ptr,
".0", 2);
998 else if (decpt > -4) {
1002 rb_str_resize(s, (
len = RSTRING_LEN(s)) - decpt + digs);
1003 ptr = RSTRING_PTR(s);
1004 memset(ptr +=
len,
'0', -decpt);
1005 memcpy(ptr -= decpt, buf, digs);
1014 memmove(buf + 2, buf + 1, digs - 1);
1022 rb_str_catf(s,
"e%+03d", decpt - 1);
1050rb_float_uminus(
VALUE flt)
1081 else if (RB_BIGNUM_TYPE_P(y)) {
1112 else if (RB_BIGNUM_TYPE_P(y)) {
1143 else if (RB_BIGNUM_TYPE_P(y)) {
1155double_div_double(
double x,
double y)
1157 if (LIKELY(y != 0.0)) {
1160 else if (x == 0.0) {
1164 double z = signbit(y) ? -1.0 : 1.0;
1165 return x * z * HUGE_VAL;
1174 double ret = double_div_double(num, den);
1202 else if (RB_BIGNUM_TYPE_P(y)) {
1203 den = rb_big2dbl(y);
1212 ret = double_div_double(num, den);
1233 return num_funcall1(x,
'/', y);
1237flodivmod(
double x,
double y,
double *divp,
double *modp)
1243 if (modp) *modp = y;
1244 if (divp) *divp = y;
1248 if ((x == 0.0) || (isinf(y) && !isinf(x)))
1260 if (isinf(x) && !isinf(y))
1263 div = (x - mod) / y;
1264 if (modp && divp) div = round(div);
1270 if (modp) *modp = mod;
1271 if (divp) *divp = div;
1280ruby_float_mod(
double x,
double y)
1283 flodivmod(x, y, 0, &mod);
1324 else if (RB_BIGNUM_TYPE_P(y)) {
1342 return rb_dbl2big(d);
1374 double fy, div, mod;
1375 volatile VALUE a, b;
1380 else if (RB_BIGNUM_TYPE_P(y)) {
1422 else if (RB_BIGNUM_TYPE_P(y)) {
1429 if (dx < 0 && dy != round(dy))
1430 return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
1464 if (RB_BIGNUM_TYPE_P(x)) {
1465 return rb_big_eql(x, y);
1491 if (x == y)
return INT2FIX(0);
1499 if (x == y)
return Qtrue;
1500 result = num_funcall1(y, id_eq, x);
1501 return RBOOL(
RTEST(result));
1524 volatile double a, b;
1527 return rb_integer_float_eq(y, x);
1533 return num_equal(x, y);
1536 return RBOOL(a == b);
1539#define flo_eq rb_float_equal
1540static VALUE rb_dbl_hash(
double d);
1558rb_dbl_hash(
double d)
1560 return ST2FIX(rb_dbl_long_hash(d));
1566 if (isnan(a) || isnan(b))
return Qnil;
1567 if (a == b)
return INT2FIX(0);
1569 if (a < b)
return INT2FIX(-1);
1610 if (isnan(a))
return Qnil;
1612 VALUE rel = rb_integer_float_cmp(y, x);
1621 if (isinf(a) && !UNDEF_P(i =
rb_check_funcall(y, rb_intern(
"infinite?"), 0, 0))) {
1623 int j = rb_cmpint(i, x, y);
1624 j = (a > 0.0) ? (j > 0 ? 0 : +1) : (j < 0 ? 0 : -1);
1627 if (a > 0.0)
return INT2FIX(1);
1638 return NUM2INT(ensure_cmp(flo_cmp(x, y), x, y));
1664 VALUE rel = rb_integer_float_cmp(y, x);
1675 return RBOOL(a > b);
1702 VALUE rel = rb_integer_float_cmp(y, x);
1713 return RBOOL(a >= b);
1738 VALUE rel = rb_integer_float_cmp(y, x);
1749 return RBOOL(a < b);
1776 VALUE rel = rb_integer_float_cmp(y, x);
1787 return RBOOL(a <= b);
1814 return RBOOL(a == b);
1819#define flo_eql rb_float_eql
1822rb_float_abs(
VALUE flt)
1841flo_is_nan_p(
VALUE num)
1845 return RBOOL(isnan(value));
1872rb_flo_is_infinite_p(
VALUE num)
1877 return INT2FIX( value < 0 ? -1 : 1 );
1902rb_flo_is_finite_p(
VALUE num)
1906 return RBOOL(isfinite(value));
1910flo_nextafter(
VALUE flo,
double value)
1914 y = nextafter(x, value);
1963flo_next_float(
VALUE vx)
1965 return flo_nextafter(vx, HUGE_VAL);
2004flo_prev_float(
VALUE vx)
2006 return flo_nextafter(vx, -HUGE_VAL);
2010rb_float_floor(
VALUE num,
int ndigits)
2014 if (number == 0.0) {
2020 frexp(number, &binexp);
2021 if (float_round_overflow(ndigits, binexp))
return num;
2022 if (number > 0.0 && float_round_underflow(ndigits, binexp))
2024 if (!ACCURATE_POW10(ndigits)) {
2025 return rb_flo_floor_by_rational(num, ndigits);
2027 f = pow(10, ndigits);
2028 mul = floor(number * f);
2029 res = (mul + 1) / f;
2035 num = dbl2ival(floor(number));
2036 if (ndigits < 0) num = rb_int_floor(num, ndigits);
2042flo_ndigits(
int argc,
VALUE *argv)
2131 int ndigits = flo_ndigits(argc, argv);
2132 return rb_float_floor(num, ndigits);
2216 int ndigits = flo_ndigits(argc, argv);
2217 return rb_float_ceil(num, ndigits);
2221rb_float_ceil(
VALUE num,
int ndigits)
2226 if (number == 0.0) {
2231 frexp(number, &binexp);
2232 if (float_round_overflow(ndigits, binexp))
return num;
2233 if (number < 0.0 && float_round_underflow(ndigits, binexp))
2235 if (!ACCURATE_POW10(ndigits)) {
2236 return rb_flo_ceil_by_rational(num, ndigits);
2238 f = pow(10, ndigits);
2239 f = ceil(number * f) / f;
2243 num = dbl2ival(ceil(number));
2244 if (ndigits < 0) num = rb_int_ceil(num, ndigits);
2250int_round_zero_p(
VALUE num,
int ndigits)
2256 bytes =
sizeof(long);
2258 else if (RB_BIGNUM_TYPE_P(num)) {
2259 bytes = rb_big_size(num);
2264 return (-0.415241 * ndigits - 0.125 > bytes);
2271 if ((z * y - x) * 2 == y) {
2280 return (x + y / 2) / y * y;
2286 return (x + y / 2 - 1) / y * y;
2292 return (
int)rb_int_odd_p(rb_int_idiv(n, f));
2298 return int_pos_p(num);
2304 return int_neg_p(num);
2311rb_int_round(
VALUE num,
int ndigits,
enum ruby_num_rounding_mode mode)
2315 if (int_round_zero_p(num, ndigits)) {
2319 f = int_pow(10, -ndigits);
2324 x = ROUND_CALL(mode, int_round, (x, y));
2332 h = rb_int_idiv(f,
INT2FIX(2));
2333 r = rb_int_modulo(num, f);
2334 n = rb_int_minus(num, r);
2335 r = rb_int_cmp(r, h);
2336 if (FIXNUM_POSITIVE_P(r) ||
2337 (FIXNUM_ZERO_P(r) && ROUND_CALL(mode, int_half_p, (num, n, f)))) {
2338 n = rb_int_plus(n, f);
2344rb_int_floor(
VALUE num,
int ndigits)
2346 VALUE f = int_pow(10, -ndigits);
2350 if (neg) x = -x + y - 1;
2356 bool neg = int_neg_p(num);
2357 if (neg) num = rb_int_minus(rb_int_plus(rb_int_uminus(num), f),
INT2FIX(1));
2358 num = rb_int_mul(rb_int_div(num, f), f);
2359 if (neg) num = rb_int_uminus(num);
2365rb_int_ceil(
VALUE num,
int ndigits)
2367 VALUE f = int_pow(10, -ndigits);
2378 bool neg = int_neg_p(num);
2380 num = rb_int_uminus(num);
2382 num = rb_int_plus(num, rb_int_minus(f,
INT2FIX(1)));
2383 num = rb_int_mul(rb_int_div(num, f), f);
2384 if (neg) num = rb_int_uminus(num);
2390rb_int_truncate(
VALUE num,
int ndigits)
2395 if (int_round_zero_p(num, ndigits))
2397 f = int_pow(10, -ndigits);
2410 m = rb_int_modulo(num, f);
2411 if (int_neg_p(num)) {
2412 return rb_int_plus(num, rb_int_minus(f, m));
2415 return rb_int_minus(num, m);
2477 double number, f, x;
2480 enum ruby_num_rounding_mode mode;
2485 mode = rb_num_get_rounding_option(opt);
2487 if (number == 0.0) {
2491 return rb_int_round(flo_to_i(num), ndigits, mode);
2494 x = ROUND_CALL(mode, round, (number, 1.0));
2497 if (isfinite(number)) {
2499 frexp(number, &binexp);
2500 if (float_round_overflow(ndigits, binexp))
return num;
2501 if (float_round_underflow(ndigits, binexp))
return DBL2NUM(0);
2502 if (!ACCURATE_POW10(ndigits)) {
2503 return rb_flo_round_by_rational(num, ndigits, mode);
2505 f = pow(10, ndigits);
2506 x = ROUND_CALL(mode, round, (number, f));
2513float_round_overflow(
int ndigits,
int binexp)
2515 enum {float_dig = DBL_DIG+2};
2534 if (ndigits >= float_dig - (binexp > 0 ? binexp / 4 : binexp / 3 - 1)) {
2541float_round_underflow(
int ndigits,
int binexp)
2543 if (ndigits < - (binexp > 0 ? binexp / 3 + 1 : binexp / 4)) {
2570 if (f > 0.0) f = floor(f);
2571 if (f < 0.0) f = ceil(f);
2577rb_flo_to_i(
VALUE num)
2579 return flo_to_i(num);
2618flo_truncate(
int argc,
VALUE *argv,
VALUE num)
2621 return flo_ceil(argc, argv, num);
2623 return flo_floor(argc, argv, num);
2643 return flo_floor(argc, argv,
rb_Float(num));
2663 return flo_ceil(argc, argv,
rb_Float(num));
2680 return flo_round(argc, argv,
rb_Float(num));
2695num_truncate(
int argc,
VALUE *argv,
VALUE num)
2697 return flo_truncate(argc, argv,
rb_Float(num));
2701ruby_float_step_size(
double beg,
double end,
double unit,
int excl)
2703 const double epsilon = DBL_EPSILON;
2710 return unit > 0 ? beg <= end : beg >= end;
2712 n= (end - beg)/unit;
2713 err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
2714 if (err>0.5) err=0.5;
2721 d = +((n + 1) * unit) + beg;
2726 else if (beg > end) {
2734 d = +((n + 1) * unit) + beg;
2739 else if (beg > end) {
2748ruby_float_step(
VALUE from,
VALUE to,
VALUE step,
int excl,
int allow_endless)
2753 double end = (allow_endless &&
NIL_P(to)) ? (unit < 0 ? -1 : 1)*HUGE_VAL :
NUM2DBL(to);
2754 double n = ruby_float_step_size(beg, end, unit, excl);
2761 else if (unit == 0) {
2767 for (i=0; i<n; i++) {
2768 double d = i*unit+beg;
2769 if (unit >= 0 ? end < d : d < end) d = end;
2779ruby_num_interval_step_size(
VALUE from,
VALUE to,
VALUE step,
int excl)
2804 if (isinf(n))
return DBL2NUM(n);
2806 return rb_dbl2big(n);
2812 case 0:
return DBL2NUM(HUGE_VAL);
2813 case -1: cmp =
'<';
break;
2825num_step_negative_p(
VALUE num)
2835 else if (RB_BIGNUM_TYPE_P(num)) {
2837 return BIGNUM_NEGATIVE_P(num);
2842 coerce_failed(num,
INT2FIX(0));
2852 argc =
rb_scan_args(argc, argv,
"02:", to, step, &hash);
2859 if (!UNDEF_P(values[0])) {
2860 if (argc > 0) rb_raise(rb_eArgError,
"to is given twice");
2863 if (!UNDEF_P(values[1])) {
2864 if (argc > 1) rb_raise(rb_eArgError,
"step is given twice");
2873num_step_check_fix_args(
int argc,
VALUE *to,
VALUE *step,
VALUE by,
int fix_nil,
int allow_zero_step)
2881 if (argc > 1 &&
NIL_P(*step)) {
2886 rb_raise(rb_eArgError,
"step can't be 0");
2891 desc = num_step_negative_p(*step);
2892 if (fix_nil &&
NIL_P(*to)) {
2899num_step_scan_args(
int argc,
const VALUE *argv,
VALUE *to,
VALUE *step,
int fix_nil,
int allow_zero_step)
2902 argc = num_step_extract_args(argc, argv, to, step, &by);
2903 return num_step_check_fix_args(argc, to, step, by, fix_nil, allow_zero_step);
2913 num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
2915 return ruby_num_interval_step_size(from, to, step, FALSE);
3023 num_step_extract_args(argc, argv, &to, &step, &by);
3031 rb_raise(rb_eArgError,
"step can't be 0");
3035 return rb_arith_seq_new(from,
ID2SYM(rb_frame_this_func()), argc, argv,
3036 num_step_size, from, to, step, FALSE);
3042 desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
3048 inf = isinf(f) && (signbit(f) ? desc : !desc);
3064 for (; i >= end; i += diff)
3068 for (; i <= end; i += diff)
3073 else if (!ruby_float_step(from, to, step, FALSE, FALSE)) {
3081 ID cmp = desc ?
'<' :
'>';
3091out_of_range_float(
char (*pbuf)[24],
VALUE val)
3093 char *
const buf = *pbuf;
3096 snprintf(buf,
sizeof(*pbuf),
"%-.10g",
RFLOAT_VALUE(val));
3097 if ((s = strchr(buf,
' ')) != 0) *s =
'\0';
3101#define FLOAT_OUT_OF_RANGE(val, type) do { \
3103 rb_raise(rb_eRangeError, "float %s out of range of "type, \
3104 out_of_range_float(&buf, (val))); \
3107#define LONG_MIN_MINUS_ONE ((double)LONG_MIN-1)
3108#define LONG_MAX_PLUS_ONE (2*(double)(LONG_MAX/2+1))
3109#define ULONG_MAX_PLUS_ONE (2*(double)(ULONG_MAX/2+1))
3110#define LONG_MIN_MINUS_ONE_IS_LESS_THAN(n) \
3111 (LONG_MIN_MINUS_ONE == (double)LONG_MIN ? \
3113 LONG_MIN_MINUS_ONE < (n))
3120 rb_no_implicit_conversion(val,
"Integer");
3127 && LONG_MIN_MINUS_ONE_IS_LESS_THAN(
RFLOAT_VALUE(val))) {
3131 FLOAT_OUT_OF_RANGE(val,
"integer");
3134 else if (RB_BIGNUM_TYPE_P(val)) {
3135 return rb_big2long(val);
3144rb_num2ulong_internal(
VALUE val,
int *wrap_p)
3148 rb_no_implicit_conversion(val,
"Integer");
3155 return (
unsigned long)l;
3159 if (d < ULONG_MAX_PLUS_ONE && LONG_MIN_MINUS_ONE_IS_LESS_THAN(d)) {
3161 *wrap_p = d <= -1.0;
3163 return (
unsigned long)d;
3164 return (
unsigned long)(long)d;
3167 FLOAT_OUT_OF_RANGE(val,
"integer");
3170 else if (RB_BIGNUM_TYPE_P(val)) {
3172 unsigned long ul = rb_big2ulong(val);
3174 *wrap_p = BIGNUM_NEGATIVE_P(val);
3187 return rb_num2ulong_internal(val, NULL);
3193 rb_raise(
rb_eRangeError,
"integer %"PRIdVALUE
" too %s to convert to 'int'",
3194 num, num < 0 ?
"small" :
"big");
3200 rb_raise(
rb_eRangeError,
"integer %"PRIdVALUE
" too %s to convert to 'long'",
3201 num, num < 0 ?
"small" :
"big");
3204#if SIZEOF_INT < SIZEOF_LONG
3208 if ((
long)(
int)num != num) {
3214check_uint(
unsigned long num,
int sign)
3218 if (num < (
unsigned long)INT_MIN)
3219 rb_raise(
rb_eRangeError,
"integer %ld too small to convert to 'unsigned int'", (
long)num);
3224 rb_raise(
rb_eRangeError,
"integer %lu too big to convert to 'unsigned int'", num);
3250 unsigned long num = rb_num2ulong_internal(val, &wrap);
3252 check_uint(num, wrap);
3266 check_uint(num, FIXNUM_NEGATIVE_P(val));
3295NORETURN(
static void rb_out_of_short(
SIGNED_VALUE num));
3299 rb_raise(
rb_eRangeError,
"integer %"PRIdVALUE
" too %s to convert to 'short'",
3300 num, num < 0 ?
"small" :
"big");
3304check_short(
long num)
3306 if ((
long)(
short)num != num) {
3307 rb_out_of_short(num);
3312check_ushort(
unsigned long num,
int sign)
3316 if (num < (
unsigned long)SHRT_MIN)
3317 rb_raise(
rb_eRangeError,
"integer %ld too small to convert to 'unsigned short'", (
long)num);
3321 if (USHRT_MAX < num)
3322 rb_raise(
rb_eRangeError,
"integer %lu too big to convert to 'unsigned short'", num);
3348 unsigned long num = rb_num2ulong_internal(val, &wrap);
3350 check_ushort(num, wrap);
3364 check_ushort(num, FIXNUM_NEGATIVE_P(val));
3377 rb_raise(
rb_eRangeError,
"integer %ld out of range of fixnum", v);
3383#define LLONG_MIN_MINUS_ONE ((double)LLONG_MIN-1)
3384#define LLONG_MAX_PLUS_ONE (2*(double)(LLONG_MAX/2+1))
3385#define ULLONG_MAX_PLUS_ONE (2*(double)(ULLONG_MAX/2+1))
3387#define ULLONG_MAX ((unsigned LONG_LONG)LLONG_MAX*2+1)
3389#define LLONG_MIN_MINUS_ONE_IS_LESS_THAN(n) \
3390 (LLONG_MIN_MINUS_ONE == (double)LLONG_MIN ? \
3392 LLONG_MIN_MINUS_ONE < (n))
3398 rb_no_implicit_conversion(val,
"Integer");
3405 if (d < LLONG_MAX_PLUS_ONE && (LLONG_MIN_MINUS_ONE_IS_LESS_THAN(d))) {
3409 FLOAT_OUT_OF_RANGE(val,
"long long");
3412 else if (RB_BIGNUM_TYPE_P(val)) {
3413 return rb_big2ll(val);
3416 rb_no_implicit_conversion(val,
"Integer");
3427 rb_no_implicit_conversion(val,
"Integer");
3434 if (d < ULLONG_MAX_PLUS_ONE && LLONG_MIN_MINUS_ONE_IS_LESS_THAN(d)) {
3440 FLOAT_OUT_OF_RANGE(val,
"unsigned long long");
3443 else if (RB_BIGNUM_TYPE_P(val)) {
3444 return rb_big2ull(val);
3457#ifndef HAVE_UINT128_T
3460rb_uint128_from_bignum_digits_fallback(
rb_uint128_t *result, BDIGIT *digits,
size_t length)
3463 for (
long i = length - 1; i >= 0; i--) {
3465 uint64_t carry = result->parts.low >> (64 - (SIZEOF_BDIGIT * CHAR_BIT));
3466 result->parts.low = (result->parts.low << (SIZEOF_BDIGIT * CHAR_BIT)) | digits[i];
3467 result->parts.high = (result->parts.high << (SIZEOF_BDIGIT * CHAR_BIT)) | carry;
3476 if (value->parts.low == 0) {
3477 value->parts.high = ~value->parts.high + 1;
3480 value->parts.low = ~value->parts.low + 1;
3481 value->parts.high = ~value->parts.high + (value->parts.low == 0 ? 1 : 0);
3487rb_numeric_to_uint128(
VALUE x)
3493 rb_raise(
rb_eRangeError,
"negative integer cannot be converted to unsigned 128-bit integer");
3495#ifdef HAVE_UINT128_T
3496 result.value = (uint128_t)value;
3498 result.parts.low = (uint64_t)value;
3499 result.parts.high = 0;
3503 else if (RB_BIGNUM_TYPE_P(x)) {
3504 if (BIGNUM_NEGATIVE_P(x)) {
3505 rb_raise(
rb_eRangeError,
"negative integer cannot be converted to unsigned 128-bit integer");
3507 size_t length = BIGNUM_LEN(x);
3508#ifdef HAVE_UINT128_T
3509 if (length > roomof(SIZEOF_INT128_T, SIZEOF_BDIGIT)) {
3510 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'unsigned 128-bit integer'");
3512 BDIGIT *digits = BIGNUM_DIGITS(x);
3514 for (
long i = length - 1; i >= 0; i--) {
3515 result.value = (result.value << (SIZEOF_BDIGIT * CHAR_BIT)) | digits[i];
3519 if (length > roomof(16, SIZEOF_BDIGIT)) {
3520 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'unsigned 128-bit integer'");
3522 BDIGIT *digits = BIGNUM_DIGITS(x);
3523 rb_uint128_from_bignum_digits_fallback(&result, digits, length);
3533rb_numeric_to_int128(
VALUE x)
3538#ifdef HAVE_UINT128_T
3539 result.value = (int128_t)value;
3544 result.parts.low = (uint64_t)value;
3545 result.parts.high = UINT64_MAX;
3548 result.parts.low = (uint64_t)value;
3549 result.parts.high = 0;
3554 else if (RB_BIGNUM_TYPE_P(x)) {
3555 size_t length = BIGNUM_LEN(x);
3556#ifdef HAVE_UINT128_T
3557 if (length > roomof(SIZEOF_INT128_T, SIZEOF_BDIGIT)) {
3558 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'signed 128-bit integer'");
3560 BDIGIT *digits = BIGNUM_DIGITS(x);
3561 uint128_t unsigned_result = 0;
3562 for (
long i = length - 1; i >= 0; i--) {
3563 unsigned_result = (unsigned_result << (SIZEOF_BDIGIT * CHAR_BIT)) | digits[i];
3565 if (BIGNUM_NEGATIVE_P(x)) {
3568 if (unsigned_result > ((uint128_t)1 << 127)) {
3569 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'signed 128-bit integer'");
3571 result.value = -(int128_t)(unsigned_result - 1) - 1;
3575 if (unsigned_result > (((uint128_t)1 << 127) - 1)) {
3576 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'signed 128-bit integer'");
3578 result.value = (int128_t)unsigned_result;
3581 if (length > roomof(16, SIZEOF_BDIGIT)) {
3582 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'signed 128-bit integer'");
3584 BDIGIT *digits = BIGNUM_DIGITS(x);
3586 rb_uint128_from_bignum_digits_fallback(&unsigned_result, digits, length);
3587 if (BIGNUM_NEGATIVE_P(x)) {
3589 uint64_t max_neg_high = (uint64_t)1 << 63;
3590 if (unsigned_result.parts.high > max_neg_high || (unsigned_result.parts.high == max_neg_high && unsigned_result.parts.low > 0)) {
3591 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'signed 128-bit integer'");
3594 rb_uint128_twos_complement_negate(&unsigned_result);
3595 result.parts.low = unsigned_result.parts.low;
3596 result.parts.high = (int64_t)unsigned_result.parts.high;
3601 uint64_t max_pos_high = ((uint64_t)1 << 63) - 1;
3602 if (unsigned_result.parts.high > max_pos_high) {
3603 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'signed 128-bit integer'");
3605 result.parts.low = unsigned_result.parts.low;
3606 result.parts.high = unsigned_result.parts.high;
3619#ifdef HAVE_UINT128_T
3623 return rb_uint128t2big(n.value);
3627 return LONG2FIX((
long)n.parts.low);
3630 VALUE bignum = rb_ull2big(n.parts.low);
3631 if (n.parts.high > 0) {
3632 VALUE high_bignum = rb_ull2big(n.parts.high);
3634 VALUE shifted_value = rb_int_lshift(high_bignum,
INT2FIX(64));
3635 bignum = rb_int_plus(bignum, shifted_value);
3644#ifdef HAVE_UINT128_T
3648 return rb_int128t2big(n.value);
3650 int64_t high = (int64_t)n.parts.high;
3653 return LONG2FIX((
long)n.parts.low);
3659 if (n.parts.low == 0) {
3660 unsigned_value.parts.low = 0;
3661 unsigned_value.parts.high = ~n.parts.high + 1;
3664 unsigned_value.parts.low = ~n.parts.low + 1;
3665 unsigned_value.parts.high = ~n.parts.high + (unsigned_value.parts.low == 0 ? 1 : 0);
3667 VALUE bignum = rb_uint128_to_numeric(unsigned_value);
3668 return rb_int_uminus(bignum);
3675 return rb_uint128_to_numeric(conversion.uint128);
3778rb_int_odd_p(
VALUE num)
3781 return RBOOL(num & 2);
3785 return rb_big_odd_p(num);
3790int_even_p(
VALUE num)
3793 return RBOOL((num & 2) == 0);
3797 return rb_big_even_p(num);
3802rb_int_even_p(
VALUE num)
3804 return int_even_p(num);
3834 return rb_int_equal(rb_int_and(num, mask), mask);
3864 return RBOOL(!int_zero_p(rb_int_and(num, mask)));
3894 return RBOOL(int_zero_p(rb_int_and(num, mask)));
3910rb_int_succ(
VALUE num)
3916 if (RB_BIGNUM_TYPE_P(num)) {
3917 return rb_big_plus(num,
INT2FIX(1));
3919 return num_funcall1(num,
'+',
INT2FIX(1));
3922#define int_succ rb_int_succ
3938rb_int_pred(
VALUE num)
3944 if (RB_BIGNUM_TYPE_P(num)) {
3945 return rb_big_minus(num,
INT2FIX(1));
3947 return num_funcall1(num,
'-',
INT2FIX(1));
3950#define int_pred rb_int_pred
3957 switch (n = rb_enc_codelen(code, enc)) {
3958 case ONIGERR_INVALID_CODE_POINT_VALUE:
3959 rb_raise(
rb_eRangeError,
"invalid codepoint 0x%X in %s", code, rb_enc_name(enc));
3961 case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE:
3966 str = rb_enc_str_new(0, n, enc);
3967 rb_enc_mbcput(code, RSTRING_PTR(str), enc);
3968 if (rb_enc_precise_mbclen(RSTRING_PTR(str),
RSTRING_END(str), enc) != n) {
3969 rb_raise(
rb_eRangeError,
"invalid codepoint 0x%X in %s", code, rb_enc_name(enc));
4000 if (rb_num_to_uint(num, &i) == 0) {
4012 enc = rb_default_internal_encoding();
4028 rb_error_arity(argc, 0, 1);
4030 enc = rb_to_encoding(argv[0]);
4031 if (!enc) enc = rb_ascii8bit_encoding();
4041fix_uminus(
VALUE num)
4047rb_int_uminus(
VALUE num)
4050 return fix_uminus(num);
4054 return rb_big_uminus(num);
4066 char buf[
SIZEOF_VALUE*CHAR_BIT + 1], *
const e = buf +
sizeof buf, *b = e;
4071 if (base < 2 || 36 < base) {
4072 rb_raise(rb_eArgError,
"invalid radix %d", base);
4074#if SIZEOF_LONG < SIZEOF_VOIDP
4075# if SIZEOF_VOIDP == SIZEOF_LONG_LONG
4076 if ((val >= 0 && (x & 0xFFFFFFFF00000000ull)) ||
4077 (val < 0 && (x & 0xFFFFFFFF00000000ull) != 0xFFFFFFFF00000000ull)) {
4078 rb_bug(
"Unnormalized Fixnum value %p", (
void *)x);
4089 u = 1 + (
unsigned long)(-(val + 1));
4102 unsigned long idx = (u % 100) * 2;
4105 b[0] = ruby_decimal_digit_pairs[idx];
4106 b[1] = ruby_decimal_digit_pairs[idx + 1];
4109 unsigned long idx = u * 2;
4111 b[0] = ruby_decimal_digit_pairs[idx];
4112 b[1] = ruby_decimal_digit_pairs[idx + 1];
4115 *--b = (char)(
'0' + u);
4120 *--b = ruby_digitmap[(int)(u % base)];
4121 }
while (u /= base);
4130static VALUE rb_fix_to_s_static[10];
4136 if (i >= 0 && i < 10) {
4137 return rb_fix_to_s_static[i];
4169 return rb_int2str(x, base);
4173rb_int2str(
VALUE x,
int base)
4178 else if (RB_BIGNUM_TYPE_P(x)) {
4179 return rb_big2str(x, base);
4189 return rb_fix_plus_fix(x, y);
4191 else if (RB_BIGNUM_TYPE_P(y)) {
4192 return rb_big_plus(y, x);
4198 return rb_complex_plus(y, x);
4208 return fix_plus(x, y);
4233 return fix_plus(x, y);
4235 else if (RB_BIGNUM_TYPE_P(x)) {
4236 return rb_big_plus(x, y);
4245 return rb_fix_minus_fix(x, y);
4247 else if (RB_BIGNUM_TYPE_P(y)) {
4249 return rb_big_minus(x, y);
4278 return fix_minus(x, y);
4280 else if (RB_BIGNUM_TYPE_P(x)) {
4281 return rb_big_minus(x, y);
4287#define SQRT_LONG_MAX HALF_LONG_MSB
4289#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
4295 return rb_fix_mul_fix(x, y);
4297 else if (RB_BIGNUM_TYPE_P(y)) {
4302 return rb_big_mul(y, x);
4308 return rb_complex_mul(y, x);
4334 return fix_mul(x, y);
4336 else if (RB_BIGNUM_TYPE_P(x)) {
4337 return rb_big_mul(x, y);
4343accurate_in_double(
long i)
4345#if SIZEOF_LONG * CHAR_BIT > DBL_MANT_DIG
4346 return ((i < 0 ? -i : i) < (1L << DBL_MANT_DIG));
4357 if (!accurate_in_double(iy)) {
4358 return rb_big_fdiv_double(rb_int2big(
FIX2LONG(x)), rb_int2big(iy));
4360 return double_div_double(
FIX2LONG(x), iy);
4362 else if (RB_BIGNUM_TYPE_P(y)) {
4363 return rb_big_fdiv_double(rb_int2big(
FIX2LONG(x)), y);
4374int_accurate_in_double(
VALUE n)
4377 return accurate_in_double(
FIX2LONG(n));
4380#if SIZEOF_LONG * CHAR_BIT <= DBL_MANT_DIG
4382 size_t size = rb_absint_size(n, &nlz);
4383 const size_t mant_size = roomof(DBL_MANT_DIG, CHAR_BIT);
4384 if (size < mant_size)
return true;
4385 if (size > mant_size)
return false;
4386 if ((
size_t)nlz >= (CHAR_BIT * mant_size - DBL_MANT_DIG))
return true;
4395 !(int_accurate_in_double(x) && int_accurate_in_double(y))) {
4396 VALUE gcd = rb_gcd(x, y);
4397 if (!FIXNUM_ZERO_P(gcd) && gcd !=
INT2FIX(1)) {
4398 x = rb_int_idiv(x, gcd);
4399 y = rb_int_idiv(y, gcd);
4403 return fix_fdiv_double(x, y);
4405 else if (RB_BIGNUM_TYPE_P(x)) {
4406 return rb_big_fdiv_double(x, y);
4433 return DBL2NUM(rb_int_fdiv_double(x, y));
4443 return rb_fix_div_fix(x, y);
4445 else if (RB_BIGNUM_TYPE_P(y)) {
4447 return rb_big_div(x, y);
4452 return rb_flo_div_flo(
DBL2NUM(d), y);
4457 v = fix_divide(x, y,
'/');
4458 return flo_floor(0, 0, v);
4464 return rb_rational_reciprocal(y);
4472 return fix_divide(x, y,
'/');
4501 return fix_div(x, y);
4503 else if (RB_BIGNUM_TYPE_P(x)) {
4504 return rb_big_div(x, y);
4512 return fix_divide(x, y, id_div);
4537 return fix_idiv(x, y);
4539 else if (RB_BIGNUM_TYPE_P(x)) {
4540 return rb_big_idiv(x, y);
4542 return num_div(x, y);
4550 return rb_fix_mod_fix(x, y);
4552 else if (RB_BIGNUM_TYPE_P(y)) {
4554 return rb_big_modulo(x, y);
4596 return fix_mod(x, y);
4598 else if (RB_BIGNUM_TYPE_P(x)) {
4599 return rb_big_modulo(x, y);
4601 return num_modulo(x, y);
4632 VALUE z = fix_mod(x, y);
4635 z = fix_minus(z, y);
4638 else if (!RB_BIGNUM_TYPE_P(y)) {
4639 return num_remainder(x, y);
4643 else if (!RB_BIGNUM_TYPE_P(x)) {
4646 return rb_big_remainder(x, y);
4655 rb_fix_divmod_fix(x, y, &div, &mod);
4658 else if (RB_BIGNUM_TYPE_P(y)) {
4660 return rb_big_divmod(x, y);
4665 volatile VALUE a, b;
4707 return fix_divmod(x, y);
4709 else if (RB_BIGNUM_TYPE_P(x)) {
4710 return rb_big_divmod(x, y);
4732int_pow(
long x,
unsigned long y)
4737 if (y == 0)
return INT2FIX(1);
4746 while (y % 2 == 0) {
4747 if (!FIT_SQRT_LONG(x)) {
4754 if (MUL_OVERFLOW_FIXNUM_P(x, z)) {
4765 v = rb_big_pow(rb_int2big(x),
LONG2NUM(y));
4768 if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
4775 return int_pow(x, y);
4786 VALUE y = rb_int_pow(x, minusb);
4806 if (a == 1)
return INT2FIX(1);
4807 if (a == -1)
return INT2FIX(b % 2 ? -1 : 1);
4808 if (b < 0)
return fix_pow_inverted(x, fix_uminus(y));
4809 if (b == 0)
return INT2FIX(1);
4810 if (b == 1)
return x;
4811 if (a == 0)
return INT2FIX(0);
4812 return int_pow(a, b);
4814 else if (RB_BIGNUM_TYPE_P(y)) {
4815 if (a == 1)
return INT2FIX(1);
4816 if (a == -1)
return INT2FIX(int_even_p(y) ? 1 : -1);
4817 if (BIGNUM_NEGATIVE_P(y))
return fix_pow_inverted(x, rb_big_uminus(y));
4818 if (a == 0)
return INT2FIX(0);
4820 return rb_big_pow(x, y);
4824 if (dy == 0.0)
return DBL2NUM(1.0);
4826 return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0);
4828 if (a == 1)
return DBL2NUM(1.0);
4829 if (a < 0 && dy != round(dy))
4830 return rb_dbl_complex_new_polar_pi(pow(-(
double)a, dy), dy);
4831 return DBL2NUM(pow((
double)a, dy));
4887 return fix_pow(x, y);
4889 else if (RB_BIGNUM_TYPE_P(x)) {
4890 return rb_big_pow(x, y);
4898 VALUE z = rb_int_pow(x, y);
4899 if (!
NIL_P(z))
return z;
4904 return rb_complex_pow(x, y);
4906 return rb_rational_pow(x, y);
4916 if (x == y)
return Qtrue;
4918 else if (RB_BIGNUM_TYPE_P(y)) {
4919 return rb_big_eq(y, x);
4922 return rb_integer_float_eq(x, y);
4925 return num_equal(x, y);
4945 return fix_equal(x, y);
4947 else if (RB_BIGNUM_TYPE_P(x)) {
4948 return rb_big_eq(x, y);
4956 if (x == y)
return INT2FIX(0);
4961 else if (RB_BIGNUM_TYPE_P(y)) {
4962 VALUE cmp = rb_big_cmp(y, x);
4970 return rb_integer_float_cmp(x, y);
5008 return fix_cmp(x, y);
5010 else if (RB_BIGNUM_TYPE_P(x)) {
5011 return rb_big_cmp(x, y);
5024 else if (RB_BIGNUM_TYPE_P(y)) {
5025 return RBOOL(rb_big_cmp(y, x) ==
INT2FIX(-1));
5028 return RBOOL(rb_integer_float_cmp(x, y) ==
INT2FIX(1));
5056 return fix_gt(x, y);
5058 else if (RB_BIGNUM_TYPE_P(x)) {
5059 return rb_big_gt(x, y);
5070 else if (RB_BIGNUM_TYPE_P(y)) {
5071 return RBOOL(rb_big_cmp(y, x) !=
INT2FIX(+1));
5074 VALUE rel = rb_integer_float_cmp(x, y);
5103 return fix_ge(x, y);
5105 else if (RB_BIGNUM_TYPE_P(x)) {
5106 return rb_big_ge(x, y);
5117 else if (RB_BIGNUM_TYPE_P(y)) {
5118 return RBOOL(rb_big_cmp(y, x) ==
INT2FIX(+1));
5121 return RBOOL(rb_integer_float_cmp(x, y) ==
INT2FIX(-1));
5147 return fix_lt(x, y);
5149 else if (RB_BIGNUM_TYPE_P(x)) {
5150 return rb_big_lt(x, y);
5161 else if (RB_BIGNUM_TYPE_P(y)) {
5162 return RBOOL(rb_big_cmp(y, x) !=
INT2FIX(-1));
5165 VALUE rel = rb_integer_float_cmp(x, y);
5194 return fix_le(x, y);
5196 else if (RB_BIGNUM_TYPE_P(x)) {
5197 return rb_big_le(x, y);
5209rb_int_comp(
VALUE num)
5212 return fix_comp(num);
5214 else if (RB_BIGNUM_TYPE_P(num)) {
5215 return rb_big_comp(num);
5221num_funcall_bit_1(
VALUE y,
VALUE arg,
int recursive)
5226 num_funcall_op_1_recursion(x, func, y);
5236 args[0] = (
VALUE)func;
5239 do_coerce(&args[1], &args[2], TRUE);
5241 args[2], args[1], (
VALUE)args);
5244 coerce_failed(x, y);
5257 if (RB_BIGNUM_TYPE_P(y)) {
5258 return rb_big_and(y, x);
5283 return fix_and(x, y);
5285 else if (RB_BIGNUM_TYPE_P(x)) {
5286 return rb_big_and(x, y);
5299 if (RB_BIGNUM_TYPE_P(y)) {
5300 return rb_big_or(y, x);
5325 return fix_or(x, y);
5327 else if (RB_BIGNUM_TYPE_P(x)) {
5328 return rb_big_or(x, y);
5341 if (RB_BIGNUM_TYPE_P(y)) {
5342 return rb_big_xor(y, x);
5367 return fix_xor(x, y);
5369 else if (RB_BIGNUM_TYPE_P(x)) {
5370 return rb_big_xor(x, y);
5383 return rb_big_lshift(rb_int2big(val), y);
5386 return fix_rshift(val, (
unsigned long)-width);
5387 return fix_lshift(val, width);
5391fix_lshift(
long val,
unsigned long width)
5393 if (width > (SIZEOF_LONG*CHAR_BIT-1)
5394 || ((
unsigned long)val)>>(SIZEOF_LONG*CHAR_BIT-1-width) > 0) {
5395 return rb_big_lshift(rb_int2big(val),
ULONG2NUM(width));
5422 return rb_fix_lshift(x, y);
5424 else if (RB_BIGNUM_TYPE_P(x)) {
5425 return rb_big_lshift(x, y);
5438 return rb_big_rshift(rb_int2big(val), y);
5440 if (i == 0)
return x;
5442 return fix_lshift(val, (
unsigned long)-i);
5443 return fix_rshift(val, i);
5447fix_rshift(
long val,
unsigned long i)
5449 if (i >=
sizeof(
long)*CHAR_BIT-1) {
5450 if (val < 0)
return INT2FIX(-1);
5453 val = RSHIFT(val, i);
5478 return rb_fix_rshift(x, y);
5480 else if (RB_BIGNUM_TYPE_P(x)) {
5481 return rb_big_rshift(x, y);
5494 idx = rb_big_norm(idx);
5496 if (!BIGNUM_SIGN(idx) || val >= 0)
5504 if (SIZEOF_LONG*CHAR_BIT-1 <= i) {
5505 if (val < 0)
return INT2FIX(1);
5527 return rb_cmpint(r, a, b);
5540 return rb_big_aref2(num, beg,
len);
5543 num = rb_int_rshift(num, beg);
5545 return rb_int_and(num, mask);
5558 if (!
RTEST(num_negative_p(end))) {
5559 if (!excl) end = rb_int_plus(end,
INT2FIX(1));
5560 VALUE mask = generate_mask(end);
5561 if (int_zero_p(rb_int_and(num, mask))) {
5565 rb_raise(rb_eArgError,
"The beginless range for Integer#[] results in infinity");
5573 int cmp = compare_indexes(beg, end);
5574 if (!
NIL_P(end) && cmp < 0) {
5575 VALUE len = rb_int_minus(end, beg);
5577 return int_aref2(num, beg,
len);
5579 else if (cmp == 0) {
5584 return rb_int_rshift(num, beg);
5589 return rb_fix_aref(num, arg);
5591 else if (RB_BIGNUM_TYPE_P(num)) {
5592 return rb_big_aref(num, arg);
5637int_aref(
int const argc,
VALUE *
const argv,
VALUE const num)
5641 return int_aref2(num, argv[0], argv[1]);
5643 return int_aref1(num, argv[0]);
5673 else if (RB_BIGNUM_TYPE_P(num)) {
5674 val = rb_big2dbl(num);
5694rb_int_abs(
VALUE num)
5697 return fix_abs(num);
5699 else if (RB_BIGNUM_TYPE_P(num)) {
5700 return rb_big_abs(num);
5712rb_int_size(
VALUE num)
5715 return fix_size(num);
5717 else if (RB_BIGNUM_TYPE_P(num)) {
5718 return rb_big_size_m(num);
5724rb_fix_bit_length(
VALUE fix)
5733rb_int_bit_length(
VALUE num)
5736 return rb_fix_bit_length(num);
5738 else if (RB_BIGNUM_TYPE_P(num)) {
5739 return rb_big_bit_length(num);
5745rb_fix_bit_count(
VALUE fix)
5749 rb_raise(rb_eArgError,
"bit_count is undefined for negative integers");
5750 return LONG2FIX(rb_popcount_intptr((uintptr_t)v));
5776rb_int_bit_count(
VALUE num)
5779 return rb_fix_bit_count(num);
5781 else if (RB_BIGNUM_TYPE_P(num)) {
5782 return rb_big_bit_count(num);
5788rb_fix_digits(
VALUE fix,
long base)
5796 rb_raise(rb_eArgError,
"invalid radix %ld", base);
5799 return rb_ary_new_from_args(1,
INT2FIX(0));
5815 VALUE digits, bases;
5819 if (RB_BIGNUM_TYPE_P(base))
5820 base = rb_big_norm(base);
5823 rb_raise(rb_eArgError,
"invalid radix %ld",
FIX2LONG(base));
5824 else if (RB_BIGNUM_TYPE_P(base) && BIGNUM_NEGATIVE_P(base))
5825 rb_raise(rb_eArgError,
"negative radix");
5828 return rb_fix_digits(num,
FIX2LONG(base));
5831 return rb_ary_new_from_args(1, num);
5833 if (int_lt(rb_int_div(rb_int_bit_length(num), rb_int_bit_length(base)),
INT2FIX(50))) {
5836 VALUE qr = rb_int_divmod(num, base);
5844 for (
VALUE b = base; int_le(b, num) ==
Qtrue; b = rb_int_mul(b, b)) {
5847 digits = rb_ary_new_from_args(1, num);
5851 for(i = last_idx; i >= 0; i--) {
5853 VALUE divmod = rb_int_divmod(n, b);
5881rb_int_digits(
int argc,
VALUE *argv,
VALUE num)
5886 if (rb_num_negative_p(num))
5892 rb_raise(
rb_eTypeError,
"wrong argument type %s (expected Integer)",
5894 if (RB_BIGNUM_TYPE_P(base_value))
5895 return rb_int_digits_bigbase(num, base_value);
5899 rb_raise(rb_eArgError,
"negative radix");
5901 rb_raise(rb_eArgError,
"invalid radix %ld", base);
5907 return rb_fix_digits(num, base);
5908 else if (RB_BIGNUM_TYPE_P(num))
5909 return rb_int_digits_bigbase(num,
LONG2FIX(base));
5948 for (i =
FIX2LONG(from); i <= end; i++) {
5959 ensure_cmp(c, i, to);
5998 for (i=
FIX2LONG(from); i >= end; i--) {
6009 ensure_cmp(c, i, to);
6017 return int_neg_p(num) ?
INT2FIX(0) : num;
6076 if (!
rb_scan_args(argc, argv,
"01:", &nd, &opt))
return num;
6078 mode = rb_num_get_rounding_option(opt);
6082 return rb_int_round(num, ndigits, mode);
6151 return rb_int_floor(num, ndigits);
6219 return rb_int_ceil(num, ndigits);
6246int_truncate(
int argc,
VALUE* argv,
VALUE num)
6255 return rb_int_truncate(num, ndigits);
6258#define DEFINE_INT_SQRT(rettype, prefix, argtype) \
6260prefix##_isqrt(argtype n) \
6262 if (!argtype##_IN_DOUBLE_P(n)) { \
6263 unsigned int b = bit_length(n); \
6265 rettype x = (rettype)(n >> (b/2+1)); \
6266 x |= ((rettype)1LU << (b-1)/2); \
6267 while ((t = n/x) < (argtype)x) x = (rettype)((x + t) >> 1); \
6270 rettype x = (rettype)sqrt(argtype##_TO_DOUBLE(n)); \
6273 if (x * x > n) x--; \
6277#if SIZEOF_LONG*CHAR_BIT > DBL_MANT_DIG
6278# define RB_ULONG_IN_DOUBLE_P(n) ((n) < (1UL << DBL_MANT_DIG))
6280# define RB_ULONG_IN_DOUBLE_P(n) 1
6282#define RB_ULONG_TO_DOUBLE(n) (double)(n)
6283#define RB_ULONG unsigned long
6284DEFINE_INT_SQRT(
unsigned long, rb_ulong, RB_ULONG)
6286#if 2*SIZEOF_BDIGIT > SIZEOF_LONG
6287# if 2*SIZEOF_BDIGIT*CHAR_BIT > DBL_MANT_DIG
6288# define BDIGIT_DBL_IN_DOUBLE_P(n) ((n) < ((BDIGIT_DBL)1UL << DBL_MANT_DIG))
6290# define BDIGIT_DBL_IN_DOUBLE_P(n) 1
6292# ifdef ULL_TO_DOUBLE
6293# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
6295# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
6297DEFINE_INT_SQRT(BDIGIT, rb_bdigit_dbl, BDIGIT_DBL)
6300#define domain_error(msg) \
6301 rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
6338 unsigned long n, sq;
6341 if (FIXNUM_NEGATIVE_P(num)) {
6342 domain_error(
"isqrt");
6345 sq = rb_ulong_isqrt(n);
6351 domain_error(
"isqrt");
6353 biglen = BIGNUM_LEN(num);
6354 if (biglen == 0)
return INT2FIX(0);
6355#if SIZEOF_BDIGIT <= SIZEOF_LONG
6358 n = BIGNUM_DIGITS(num)[0];
6359 sq = rb_ulong_isqrt(n);
6363 return rb_big_isqrt(num);
6386 return rb_check_integer_type(num);
6663#define fix_to_s_static(n) do { \
6664 VALUE lit = rb_fstring_literal(#n); \
6665 rb_fix_to_s_static[n] = lit; \
6666 rb_vm_register_global_object(lit); \
6681#undef fix_to_s_static
6806#undef rb_float_value
6810 return rb_float_value_inline(v);
6815rb_float_new(
double d)
6817 return rb_float_new_inline(d);
6820#include "numeric.rbinc"
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
VALUE rb_float_new_in_heap(double d)
Identical to rb_float_new(), except it does not generate Flonums.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
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.
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 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 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 T_BIGNUM
Old name of RUBY_T_BIGNUM.
#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_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 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 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.
VALUE rb_eNotImpError
NotImplementedError exception.
void rb_name_error(ID id, const char *fmt,...)
Raises an instance of rb_eNameError.
VALUE rb_eZeroDivError
ZeroDivisionError exception.
VALUE rb_eStandardError
StandardError exception.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eFloatDomainError
FloatDomainError exception.
VALUE rb_eMathDomainError
Math::DomainError exception.
VALUE rb_Float(VALUE val)
This is the logic behind Kernel#Float.
VALUE rb_cObject
Object class.
VALUE rb_any_to_s(VALUE obj)
Generates a textual representation of the given object.
VALUE rb_cInteger
Module class.
VALUE rb_cNumeric
Numeric class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
VALUE rb_mComparable
Comparable module.
VALUE rb_cFloat
Float class.
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
#define RUBY_FIXNUM_MAX
Maximum possible value that a fixnum can represent.
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
Encodes the passed code point into a series of bytes.
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.
Defines RBIMPL_HAS_BUILTIN.
void rb_ary_store(VALUE ary, rb_len_t key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
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_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
#define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat)
This is an implementation detail of RETURN_SIZED_ENUMERATOR_KW().
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
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.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US ASCII" encoding.
VALUE rb_str_cat(VALUE dst, const char *src, rb_len_t srclen)
Destructively appends the passed contents to the string.
#define rb_usascii_str_new_cstr(str)
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_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
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().
VALUE rb_sym2str(VALUE symbol)
Obtain a frozen string representation of a symbol (not including the leading colon).
ID rb_to_id(VALUE str)
Identical to rb_intern_str(), except it tries to convert the parameter object to an instance of rb_cS...
int len
Length of the buffer.
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().
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_yield(VALUE val)
Yields the block.
#define RB_FIX2ULONG
Just another name of rb_fix2ulong.
#define RB_FIX2LONG
Just another name of rb_fix2long.
void rb_out_of_int(SIGNED_VALUE num)
This is an utility function to raise an rb_eRangeError.
void rb_out_of_long(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.
static char * RSTRING_END(VALUE str)
Queries the end of 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().
static bool RB_FIXNUM_P(VALUE obj)
Checks if the given object is a so-called Fixnum.
#define RTEST
This is an old name of RB_TEST.
long rb_len_t
A signed integer type for lengths and indices of objects such as String and Array.
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.