Ruby: numeric.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

numeric.c
Go to the documentation of this file.
1/**********************************************************************
2
3 numeric.c -
4
5 $Author$
6 created at: Fri Aug 13 18:33:09 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10**********************************************************************/
11
12#include "ruby/internal/config.h"
13
14#include <assert.h>
15#include <ctype.h>
16#include <math.h>
17#include <stdio.h>
18
19#ifdef HAVE_FLOAT_H
20#include <float.h>
21#endif
22
23#ifdef HAVE_IEEEFP_H
24#include <ieeefp.h>
25#endif
26
27#include "id.h"
28#include "internal.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/util.h"
39#include "internal/variable.h"
40#include "ruby/encoding.h"
41#include "ruby/util.h"
42#include "builtin.h"
43
44/* use IEEE 64bit values if not defined */
45#ifndef FLT_RADIX
46#define FLT_RADIX 2
47#endif
48#ifndef DBL_MIN
49#define DBL_MIN 2.2250738585072014e-308
50#endif
51#ifndef DBL_MAX
52#define DBL_MAX 1.7976931348623157e+308
53#endif
54#ifndef DBL_MIN_EXP
55#define DBL_MIN_EXP (-1021)
56#endif
57#ifndef DBL_MAX_EXP
58#define DBL_MAX_EXP 1024
59#endif
60#ifndef DBL_MIN_10_EXP
61#define DBL_MIN_10_EXP (-307)
62#endif
63#ifndef DBL_MAX_10_EXP
64#define DBL_MAX_10_EXP 308
65#endif
66#ifndef DBL_DIG
67#define DBL_DIG 15
68#endif
69#ifndef DBL_MANT_DIG
70#define DBL_MANT_DIG 53
71#endif
72#ifndef DBL_EPSILON
73#define DBL_EPSILON 2.2204460492503131e-16
74#endif
75
76#ifndef USE_RB_INFINITY
77#elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */
78 const union bytesequence4_or_float rb_infinity = {{0x00, 0x00, 0x80, 0x7f}};
79#else
80const union bytesequence4_or_float rb_infinity = {{0x7f, 0x80, 0x00, 0x00}};
81#endif
82
83#ifndef USE_RB_NAN
84#elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */
85 const union bytesequence4_or_float rb_nan = {{0x00, 0x00, 0xc0, 0x7f}};
86#else
87const union bytesequence4_or_float rb_nan = {{0x7f, 0xc0, 0x00, 0x00}};
88#endif
89
90#ifndef HAVE_ROUND
91double
92 round(double x)
93{
94 double f;
95
96 if (x > 0.0) {
97 f = floor(x);
98 x = f + (x - f >= 0.5);
99 }
100 else if (x < 0.0) {
101 f = ceil(x);
102 x = f - (f - x >= 0.5);
103 }
104 return x;
105}
106#endif
107
108static double
109round_half_up(double x, double s)
110{
111 double f, xs = x * s;
112
113 f = round(xs);
114 if (s == 1.0) return f;
115 if (x > 0) {
116 if ((double)((f + 0.5) / s) <= x) f += 1;
117 x = f;
118 }
119 else {
120 if ((double)((f - 0.5) / s) >= x) f -= 1;
121 x = f;
122 }
123 return x;
124}
125
126static double
127round_half_down(double x, double s)
128{
129 double f, xs = x * s;
130
131 f = round(xs);
132 if (x > 0) {
133 if ((double)((f - 0.5) / s) >= x) f -= 1;
134 x = f;
135 }
136 else {
137 if ((double)((f + 0.5) / s) <= x) f += 1;
138 x = f;
139 }
140 return x;
141}
142
143static double
144round_half_even(double x, double s)
145{
146 double f, d, xs = x * s;
147
148 if (x > 0.0) {
149 f = floor(xs);
150 d = xs - f;
151 if (d > 0.5)
152 d = 1.0;
153 else if (d == 0.5 || ((double)((f + 0.5) / s) <= x))
154 d = fmod(f, 2.0);
155 else
156 d = 0.0;
157 x = f + d;
158 }
159 else if (x < 0.0) {
160 f = ceil(xs);
161 d = f - xs;
162 if (d > 0.5)
163 d = 1.0;
164 else if (d == 0.5 || ((double)((f - 0.5) / s) >= x))
165 d = fmod(-f, 2.0);
166 else
167 d = 0.0;
168 x = f - d;
169 }
170 return x;
171}
172
173static VALUE fix_lshift(long, unsigned long);
174static VALUE fix_rshift(long, unsigned long);
175static VALUE int_pow(long x, unsigned long y);
176static VALUE rb_int_floor(VALUE num, int ndigits);
177static VALUE rb_int_ceil(VALUE num, int ndigits);
178static VALUE flo_to_i(VALUE num);
179static int float_round_overflow(int ndigits, int binexp);
180static int float_round_underflow(int ndigits, int binexp);
181
182static ID id_coerce;
183#define id_div idDiv
184#define id_divmod idDivmod
185#define id_to_i idTo_i
186#define id_eq idEq
187#define id_cmp idCmp
188
189 VALUE rb_cNumeric;
190 VALUE rb_cFloat;
191 VALUE rb_cInteger;
192
193 VALUE rb_eZeroDivError;
194 VALUE rb_eFloatDomainError;
195
196static ID id_to, id_by;
197
198void
199 rb_num_zerodiv(void)
200{
201 rb_raise(rb_eZeroDivError, "divided by 0");
202}
203
204enum ruby_num_rounding_mode
205 rb_num_get_rounding_option(VALUE opts)
206{
207 static ID round_kwds[1];
208 VALUE rounding;
209 VALUE str;
210 const char *s;
211
212 if (!NIL_P(opts)) {
213 if (!round_kwds[0]) {
214 round_kwds[0] = rb_intern_const("half");
215 }
216 if (!rb_get_kwargs(opts, round_kwds, 0, 1, &rounding)) goto noopt;
217 if (SYMBOL_P(rounding)) {
218 str = rb_sym2str(rounding);
219 }
220 else if (NIL_P(rounding)) {
221 goto noopt;
222 }
223 else if (!RB_TYPE_P(str = rounding, T_STRING)) {
224 str = rb_check_string_type(rounding);
225 if (NIL_P(str)) goto invalid;
226 }
227 rb_must_asciicompat(str);
228 s = RSTRING_PTR(str);
229 switch (RSTRING_LEN(str)) {
230 case 2:
231 if (rb_memcicmp(s, "up", 2) == 0)
232 return RUBY_NUM_ROUND_HALF_UP;
233 break;
234 case 4:
235 if (rb_memcicmp(s, "even", 4) == 0)
236 return RUBY_NUM_ROUND_HALF_EVEN;
237 if (strncasecmp(s, "down", 4) == 0)
238 return RUBY_NUM_ROUND_HALF_DOWN;
239 break;
240 }
241 invalid:
242 rb_raise(rb_eArgError, "invalid rounding mode: % "PRIsVALUE, rounding);
243 }
244 noopt:
245 return RUBY_NUM_ROUND_DEFAULT;
246}
247
248/* experimental API */
249int
250 rb_num_to_uint(VALUE val, unsigned int *ret)
251{
252#define NUMERR_TYPE 1
253#define NUMERR_NEGATIVE 2
254#define NUMERR_TOOLARGE 3
255 if (FIXNUM_P(val)) {
256 long v = FIX2LONG(val);
257#if SIZEOF_INT < SIZEOF_LONG
258 if (v > (long)UINT_MAX) return NUMERR_TOOLARGE;
259#endif
260 if (v < 0) return NUMERR_NEGATIVE;
261 *ret = (unsigned int)v;
262 return 0;
263 }
264
265 if (RB_TYPE_P(val, T_BIGNUM)) {
266 if (BIGNUM_NEGATIVE_P(val)) return NUMERR_NEGATIVE;
267#if SIZEOF_INT < SIZEOF_LONG
268 /* long is 64bit */
269 return NUMERR_TOOLARGE;
270#else
271 /* long is 32bit */
272 if (rb_absint_size(val, NULL) > sizeof(int)) return NUMERR_TOOLARGE;
273 *ret = (unsigned int)rb_big2ulong((VALUE)val);
274 return 0;
275#endif
276 }
277 return NUMERR_TYPE;
278}
279
280#define method_basic_p(klass) rb_method_basic_definition_p(klass, mid)
281
282static inline int
283int_pos_p(VALUE num)
284{
285 if (FIXNUM_P(num)) {
286 return FIXNUM_POSITIVE_P(num);
287 }
288 else if (RB_TYPE_P(num, T_BIGNUM)) {
289 return BIGNUM_POSITIVE_P(num);
290 }
291 rb_raise(rb_eTypeError, "not an Integer");
292}
293
294static inline int
295int_neg_p(VALUE num)
296{
297 if (FIXNUM_P(num)) {
298 return FIXNUM_NEGATIVE_P(num);
299 }
300 else if (RB_TYPE_P(num, T_BIGNUM)) {
301 return BIGNUM_NEGATIVE_P(num);
302 }
303 rb_raise(rb_eTypeError, "not an Integer");
304}
305
306int
307 rb_int_positive_p(VALUE num)
308{
309 return int_pos_p(num);
310}
311
312int
313 rb_int_negative_p(VALUE num)
314{
315 return int_neg_p(num);
316}
317
318int
319 rb_num_negative_p(VALUE num)
320{
321 return rb_num_negative_int_p(num);
322}
323
324static VALUE
325num_funcall_op_0(VALUE x, VALUE arg, int recursive)
326{
327 ID func = (ID)arg;
328 if (recursive) {
329 const char *name = rb_id2name(func);
330 if (ISALNUM(name[0])) {
331 rb_name_error(func, "%"PRIsVALUE".%"PRIsVALUE,
332 x, ID2SYM(func));
333 }
334 else if (name[0] && name[1] == '@' && !name[2]) {
335 rb_name_error(func, "%c%"PRIsVALUE,
336 name[0], x);
337 }
338 else {
339 rb_name_error(func, "%"PRIsVALUE"%"PRIsVALUE,
340 ID2SYM(func), x);
341 }
342 }
343 return rb_funcallv(x, func, 0, 0);
344}
345
346static VALUE
347num_funcall0(VALUE x, ID func)
348{
349 return rb_exec_recursive(num_funcall_op_0, x, (VALUE)func);
350}
351
352 NORETURN(static void num_funcall_op_1_recursion(VALUE x, ID func, VALUE y));
353
354static void
355num_funcall_op_1_recursion(VALUE x, ID func, VALUE y)
356{
357 const char *name = rb_id2name(func);
358 if (ISALNUM(name[0])) {
359 rb_name_error(func, "%"PRIsVALUE".%"PRIsVALUE"(%"PRIsVALUE")",
360 x, ID2SYM(func), y);
361 }
362 else {
363 rb_name_error(func, "%"PRIsVALUE"%"PRIsVALUE"%"PRIsVALUE,
364 x, ID2SYM(func), y);
365 }
366}
367
368static VALUE
369num_funcall_op_1(VALUE y, VALUE arg, int recursive)
370{
371 ID func = (ID)((VALUE *)arg)[0];
372 VALUE x = ((VALUE *)arg)[1];
373 if (recursive) {
374 num_funcall_op_1_recursion(x, func, y);
375 }
376 return rb_funcall(x, func, 1, y);
377}
378
379static VALUE
380num_funcall1(VALUE x, ID func, VALUE y)
381{
382 VALUE args[2];
383 args[0] = (VALUE)func;
384 args[1] = x;
385 return rb_exec_recursive_paired(num_funcall_op_1, y, x, (VALUE)args);
386}
387
388/*
389 * call-seq:
390 * num.coerce(numeric) -> array
391 *
392 * If +numeric+ is the same type as +num+, returns an array
393 * <code>[numeric, num]</code>. Otherwise, returns an array with both
394 * +numeric+ and +num+ represented as Float objects.
395 *
396 * This coercion mechanism is used by Ruby to handle mixed-type numeric
397 * operations: it is intended to find a compatible common type between the two
398 * operands of the operator.
399 *
400 * 1.coerce(2.5) #=> [2.5, 1.0]
401 * 1.2.coerce(3) #=> [3.0, 1.2]
402 * 1.coerce(2) #=> [2, 1]
403 */
404
405static VALUE
406num_coerce(VALUE x, VALUE y)
407{
408 if (CLASS_OF(x) == CLASS_OF(y))
409 return rb_assoc_new(y, x);
410 x = rb_Float(x);
411 y = rb_Float(y);
412 return rb_assoc_new(y, x);
413}
414
415 NORETURN(static void coerce_failed(VALUE x, VALUE y));
416static void
417coerce_failed(VALUE x, VALUE y)
418{
419 if (SPECIAL_CONST_P(y) || SYMBOL_P(y) || RB_FLOAT_TYPE_P(y)) {
420 y = rb_inspect(y);
421 }
422 else {
423 y = rb_obj_class(y);
424 }
425 rb_raise(rb_eTypeError, "%"PRIsVALUE" can't be coerced into %"PRIsVALUE,
426 y, rb_obj_class(x));
427}
428
429static int
430do_coerce(VALUE *x, VALUE *y, int err)
431{
432 VALUE ary = rb_check_funcall(*y, id_coerce, 1, x);
433 if (ary == Qundef) {
434 if (err) {
435 coerce_failed(*x, *y);
436 }
437 return FALSE;
438 }
439 if (!err && NIL_P(ary)) {
440 return FALSE;
441 }
442 if (!RB_TYPE_P(ary, T_ARRAY) || RARRAY_LEN(ary) != 2) {
443 rb_raise(rb_eTypeError, "coerce must return [x, y]");
444 }
445
446 *x = RARRAY_AREF(ary, 0);
447 *y = RARRAY_AREF(ary, 1);
448 return TRUE;
449}
450
451 VALUE
452 rb_num_coerce_bin(VALUE x, VALUE y, ID func)
453{
454 do_coerce(&x, &y, TRUE);
455 return rb_funcall(x, func, 1, y);
456}
457
458 VALUE
459 rb_num_coerce_cmp(VALUE x, VALUE y, ID func)
460{
461 if (do_coerce(&x, &y, FALSE))
462 return rb_funcall(x, func, 1, y);
463 return Qnil;
464}
465
466static VALUE
467ensure_cmp(VALUE c, VALUE x, VALUE y)
468{
469 if (NIL_P(c)) rb_cmperr(x, y);
470 return c;
471}
472
473 VALUE
474 rb_num_coerce_relop(VALUE x, VALUE y, ID func)
475{
476 VALUE x0 = x, y0 = y;
477
478 if (!do_coerce(&x, &y, FALSE)) {
479 rb_cmperr(x0, y0);
480 UNREACHABLE_RETURN(Qnil);
481 }
482 return ensure_cmp(rb_funcall(x, func, 1, y), x0, y0);
483}
484
485 NORETURN(static VALUE num_sadded(VALUE x, VALUE name));
486
487/*
488 * :nodoc:
489 *
490 * Trap attempts to add methods to Numeric objects. Always raises a TypeError.
491 *
492 * Numerics should be values; singleton_methods should not be added to them.
493 */
494
495static VALUE
496num_sadded(VALUE x, VALUE name)
497{
498 ID mid = rb_to_id(name);
499 /* ruby_frame = ruby_frame->prev; */ /* pop frame for "singleton_method_added" */
500 rb_remove_method_id(rb_singleton_class(x), mid);
501 rb_raise(rb_eTypeError,
502 "can't define singleton method \"%"PRIsVALUE"\" for %"PRIsVALUE,
503 rb_id2str(mid),
504 rb_obj_class(x));
505
506 UNREACHABLE_RETURN(Qnil);
507}
508
509#if 0
510/*
511 * call-seq:
512 * num.clone(freeze: true) -> num
513 *
514 * Returns the receiver. +freeze+ cannot be +false+.
515 */
516static VALUE
517 num_clone(int argc, VALUE *argv, VALUE x)
518{
519 return rb_immutable_obj_clone(argc, argv, x);
520}
521#else
522# define num_clone rb_immutable_obj_clone
523#endif
524
525#if 0
526/*
527 * call-seq:
528 * num.dup -> num
529 *
530 * Returns the receiver.
531 */
532static VALUE
533 num_dup(VALUE x)
534{
535 return x;
536}
537#else
538# define num_dup num_uplus
539#endif
540
541/*
542 * call-seq:
543 * +num -> num
544 *
545 * Unary Plus---Returns the receiver.
546 */
547
548static VALUE
549num_uplus(VALUE num)
550{
551 return num;
552}
553
554/*
555 * call-seq:
556 * num.i -> Complex(0, num)
557 *
558 * Returns the corresponding imaginary number.
559 * Not available for complex numbers.
560 *
561 * -42.i #=> (0-42i)
562 * 2.0.i #=> (0+2.0i)
563 */
564
565static VALUE
566num_imaginary(VALUE num)
567{
568 return rb_complex_new(INT2FIX(0), num);
569}
570
571/*
572 * call-seq:
573 * -num -> numeric
574 *
575 * Unary Minus---Returns the receiver, negated.
576 */
577
578static VALUE
579num_uminus(VALUE num)
580{
581 VALUE zero;
582
583 zero = INT2FIX(0);
584 do_coerce(&zero, &num, TRUE);
585
586 return num_funcall1(zero, '-', num);
587}
588
589/*
590 * call-seq:
591 * num.fdiv(numeric) -> float
592 *
593 * Returns float division.
594 */
595
596static VALUE
597num_fdiv(VALUE x, VALUE y)
598{
599 return rb_funcall(rb_Float(x), '/', 1, y);
600}
601
602/*
603 * call-seq:
604 * num.div(numeric) -> integer
605 *
606 * Uses +/+ to perform division, then converts the result to an integer.
607 * Numeric does not define the +/+ operator; this is left to subclasses.
608 *
609 * Equivalent to <code>num.divmod(numeric)[0]</code>.
610 *
611 * See Numeric#divmod.
612 */
613
614static VALUE
615num_div(VALUE x, VALUE y)
616{
617 if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
618 return rb_funcall(num_funcall1(x, '/', y), rb_intern("floor"), 0);
619}
620
621/*
622 * call-seq:
623 * num.modulo(numeric) -> real
624 *
625 * <code>x.modulo(y)</code> means <code>x-y*(x/y).floor</code>.
626 *
627 * Equivalent to <code>num.divmod(numeric)[1]</code>.
628 *
629 * See Numeric#divmod.
630 */
631
632static VALUE
633num_modulo(VALUE x, VALUE y)
634{
635 VALUE q = num_funcall1(x, id_div, y);
636 return rb_funcall(x, '-', 1,
637 rb_funcall(y, '*', 1, q));
638}
639
640/*
641 * call-seq:
642 * num.remainder(numeric) -> real
643 *
644 * <code>x.remainder(y)</code> means <code>x-y*(x/y).truncate</code>.
645 *
646 * See Numeric#divmod.
647 */
648
649static VALUE
650num_remainder(VALUE x, VALUE y)
651{
652 VALUE z = num_funcall1(x, '%', y);
653
654 if ((!rb_equal(z, INT2FIX(0))) &&
655 ((rb_num_negative_int_p(x) &&
656 rb_num_positive_int_p(y)) ||
657 (rb_num_positive_int_p(x) &&
658 rb_num_negative_int_p(y)))) {
659 return rb_funcall(z, '-', 1, y);
660 }
661 return z;
662}
663
664/*
665 * call-seq:
666 * num.divmod(numeric) -> array
667 *
668 * Returns an array containing the quotient and modulus obtained by dividing
669 * +num+ by +numeric+.
670 *
671 * If <code>q, r = x.divmod(y)</code>, then
672 *
673 * q = floor(x/y)
674 * x = q*y + r
675 *
676 * The quotient is rounded toward negative infinity, as shown in the
677 * following table:
678 *
679 * a | b | a.divmod(b) | a/b | a.modulo(b) | a.remainder(b)
680 * ------+-----+---------------+---------+-------------+---------------
681 * 13 | 4 | 3, 1 | 3 | 1 | 1
682 * ------+-----+---------------+---------+-------------+---------------
683 * 13 | -4 | -4, -3 | -4 | -3 | 1
684 * ------+-----+---------------+---------+-------------+---------------
685 * -13 | 4 | -4, 3 | -4 | 3 | -1
686 * ------+-----+---------------+---------+-------------+---------------
687 * -13 | -4 | 3, -1 | 3 | -1 | -1
688 * ------+-----+---------------+---------+-------------+---------------
689 * 11.5 | 4 | 2, 3.5 | 2.875 | 3.5 | 3.5
690 * ------+-----+---------------+---------+-------------+---------------
691 * 11.5 | -4 | -3, -0.5 | -2.875 | -0.5 | 3.5
692 * ------+-----+---------------+---------+-------------+---------------
693 * -11.5 | 4 | -3, 0.5 | -2.875 | 0.5 | -3.5
694 * ------+-----+---------------+---------+-------------+---------------
695 * -11.5 | -4 | 2, -3.5 | 2.875 | -3.5 | -3.5
696 *
697 *
698 * Examples
699 *
700 * 11.divmod(3) #=> [3, 2]
701 * 11.divmod(-3) #=> [-4, -1]
702 * 11.divmod(3.5) #=> [3, 0.5]
703 * (-11).divmod(3.5) #=> [-4, 3.0]
704 * 11.5.divmod(3.5) #=> [3, 1.0]
705 */
706
707static VALUE
708num_divmod(VALUE x, VALUE y)
709{
710 return rb_assoc_new(num_div(x, y), num_modulo(x, y));
711}
712
713/*
714 * call-seq:
715 * num.real? -> true or false
716 *
717 * Returns +true+ if +num+ is a real number (i.e. not Complex).
718 */
719
720static VALUE
721num_real_p(VALUE num)
722{
723 return Qtrue;
724}
725
726/*
727 * call-seq:
728 * num.integer? -> true or false
729 *
730 * Returns +true+ if +num+ is an Integer.
731 *
732 * 1.0.integer? #=> false
733 * 1.integer? #=> true
734 */
735
736static VALUE
737num_int_p(VALUE num)
738{
739 return Qfalse;
740}
741
742/*
743 * call-seq:
744 * num.abs -> numeric
745 * num.magnitude -> numeric
746 *
747 * Returns the absolute value of +num+.
748 *
749 * 12.abs #=> 12
750 * (-34.56).abs #=> 34.56
751 * -34.56.abs #=> 34.56
752 *
753 * Numeric#magnitude is an alias for Numeric#abs.
754 */
755
756static VALUE
757num_abs(VALUE num)
758{
759 if (rb_num_negative_int_p(num)) {
760 return num_funcall0(num, idUMinus);
761 }
762 return num;
763}
764
765/*
766 * call-seq:
767 * num.zero? -> true or false
768 *
769 * Returns +true+ if +num+ has a zero value.
770 */
771
772static VALUE
773num_zero_p(VALUE num)
774{
775 if (rb_equal(num, INT2FIX(0))) {
776 return Qtrue;
777 }
778 return Qfalse;
779}
780
781static VALUE
782int_zero_p(VALUE num)
783{
784 if (FIXNUM_P(num)) {
785 if (FIXNUM_ZERO_P(num)) {
786 return Qtrue;
787 }
788 }
789 else {
790 assert(RB_TYPE_P(num, T_BIGNUM));
791 if (rb_bigzero_p(num)) {
792 /* this should not happen usually */
793 return Qtrue;
794 }
795 }
796 return Qfalse;
797}
798
799 VALUE
800 rb_int_zero_p(VALUE num)
801{
802 return int_zero_p(num);
803}
804
805/*
806 * call-seq:
807 * num.nonzero? -> self or nil
808 *
809 * Returns +self+ if +num+ is not zero, +nil+ otherwise.
810 *
811 * This behavior is useful when chaining comparisons:
812 *
813 * a = %w( z Bb bB bb BB a aA Aa AA A )
814 * b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
815 * b #=> ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
816 */
817
818static VALUE
819num_nonzero_p(VALUE num)
820{
821 if (RTEST(num_funcall0(num, rb_intern("zero?")))) {
822 return Qnil;
823 }
824 return num;
825}
826
827/*
828 * call-seq:
829 * num.finite? -> true or false
830 *
831 * Returns +true+ if +num+ is a finite number, otherwise returns +false+.
832 */
833static VALUE
834num_finite_p(VALUE num)
835{
836 return Qtrue;
837}
838
839/*
840 * call-seq:
841 * num.infinite? -> -1, 1, or nil
842 *
843 * Returns +nil+, -1, or 1 depending on whether the value is
844 * finite, <code>-Infinity</code>, or <code>+Infinity</code>.
845 */
846static VALUE
847num_infinite_p(VALUE num)
848{
849 return Qnil;
850}
851
852/*
853 * call-seq:
854 * num.to_int -> integer
855 *
856 * Invokes the child class's +to_i+ method to convert +num+ to an integer.
857 *
858 * 1.0.class #=> Float
859 * 1.0.to_int.class #=> Integer
860 * 1.0.to_i.class #=> Integer
861 */
862
863static VALUE
864num_to_int(VALUE num)
865{
866 return num_funcall0(num, id_to_i);
867}
868
869/*
870 * call-seq:
871 * num.positive? -> true or false
872 *
873 * Returns +true+ if +num+ is greater than 0.
874 */
875
876static VALUE
877num_positive_p(VALUE num)
878{
879 const ID mid = '>';
880
881 if (FIXNUM_P(num)) {
882 if (method_basic_p(rb_cInteger))
883 return (SIGNED_VALUE)num > (SIGNED_VALUE)INT2FIX(0) ? Qtrue : Qfalse;
884 }
885 else if (RB_TYPE_P(num, T_BIGNUM)) {
886 if (method_basic_p(rb_cInteger))
887 return BIGNUM_POSITIVE_P(num) && !rb_bigzero_p(num) ? Qtrue : Qfalse;
888 }
889 return rb_num_compare_with_zero(num, mid);
890}
891
892/*
893 * call-seq:
894 * num.negative? -> true or false
895 *
896 * Returns +true+ if +num+ is less than 0.
897 */
898
899static VALUE
900num_negative_p(VALUE num)
901{
902 return rb_num_negative_int_p(num) ? Qtrue : Qfalse;
903}
904
905
906/********************************************************************
907 *
908 * Document-class: Float
909 *
910 * Float objects represent inexact real numbers using the native
911 * architecture's double-precision floating point representation.
912 *
913 * Floating point has a different arithmetic and is an inexact number.
914 * So you should know its esoteric system. See following:
915 *
916 * - https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
917 * - https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#floats_imprecise
918 * - https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
919 */
920
921 VALUE
922 rb_float_new_in_heap(double d)
923{
924 NEWOBJ_OF(flt, struct RFloat, rb_cFloat, T_FLOAT | (RGENGC_WB_PROTECTED_FLOAT ? FL_WB_PROTECTED : 0));
925
926 flt->float_value = d;
927 OBJ_FREEZE((VALUE)flt);
928 return (VALUE)flt;
929}
930
931/*
932 * call-seq:
933 * float.to_s -> string
934 *
935 * Returns a string containing a representation of +self+.
936 * As well as a fixed or exponential form of the +float+,
937 * the call may return +NaN+, +Infinity+, and +-Infinity+.
938 */
939
940static VALUE
941flo_to_s(VALUE flt)
942{
943 enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
944 enum {float_dig = DBL_DIG+1};
945 char buf[float_dig + (decimal_mant + CHAR_BIT - 1) / CHAR_BIT + 10];
946 double value = RFLOAT_VALUE(flt);
947 VALUE s;
948 char *p, *e;
949 int sign, decpt, digs;
950
951 if (isinf(value)) {
952 static const char minf[] = "-Infinity";
953 const int pos = (value > 0); /* skip "-" */
954 return rb_usascii_str_new(minf+pos, strlen(minf)-pos);
955 }
956 else if (isnan(value))
957 return rb_usascii_str_new2("NaN");
958
959 p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
960 s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
961 if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
962 memcpy(buf, p, digs);
963 xfree(p);
964 if (decpt > 0) {
965 if (decpt < digs) {
966 memmove(buf + decpt + 1, buf + decpt, digs - decpt);
967 buf[decpt] = '.';
968 rb_str_cat(s, buf, digs + 1);
969 }
970 else if (decpt <= DBL_DIG) {
971 long len;
972 char *ptr;
973 rb_str_cat(s, buf, digs);
974 rb_str_resize(s, (len = RSTRING_LEN(s)) + decpt - digs + 2);
975 ptr = RSTRING_PTR(s) + len;
976 if (decpt > digs) {
977 memset(ptr, '0', decpt - digs);
978 ptr += decpt - digs;
979 }
980 memcpy(ptr, ".0", 2);
981 }
982 else {
983 goto exp;
984 }
985 }
986 else if (decpt > -4) {
987 long len;
988 char *ptr;
989 rb_str_cat(s, "0.", 2);
990 rb_str_resize(s, (len = RSTRING_LEN(s)) - decpt + digs);
991 ptr = RSTRING_PTR(s);
992 memset(ptr += len, '0', -decpt);
993 memcpy(ptr -= decpt, buf, digs);
994 }
995 else {
996 goto exp;
997 }
998 return s;
999
1000 exp:
1001 if (digs > 1) {
1002 memmove(buf + 2, buf + 1, digs - 1);
1003 }
1004 else {
1005 buf[2] = '0';
1006 digs++;
1007 }
1008 buf[1] = '.';
1009 rb_str_cat(s, buf, digs + 1);
1010 rb_str_catf(s, "e%+03d", decpt - 1);
1011 return s;
1012}
1013
1014/*
1015 * call-seq:
1016 * float.coerce(numeric) -> array
1017 *
1018 * Returns an array with both +numeric+ and +float+ represented as Float
1019 * objects.
1020 *
1021 * This is achieved by converting +numeric+ to a Float.
1022 *
1023 * 1.2.coerce(3) #=> [3.0, 1.2]
1024 * 2.5.coerce(1.1) #=> [1.1, 2.5]
1025 */
1026
1027static VALUE
1028flo_coerce(VALUE x, VALUE y)
1029{
1030 return rb_assoc_new(rb_Float(y), x);
1031}
1032
1033/*
1034 * call-seq:
1035 * -float -> float
1036 *
1037 * Returns +float+, negated.
1038 */
1039
1040 VALUE
1041 rb_float_uminus(VALUE flt)
1042{
1043 return DBL2NUM(-RFLOAT_VALUE(flt));
1044}
1045
1046/*
1047 * call-seq:
1048 * float + other -> float
1049 *
1050 * Returns a new Float which is the sum of +float+ and +other+.
1051 */
1052
1053 VALUE
1054 rb_float_plus(VALUE x, VALUE y)
1055{
1056 if (RB_TYPE_P(y, T_FIXNUM)) {
1057 return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
1058 }
1059 else if (RB_TYPE_P(y, T_BIGNUM)) {
1060 return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
1061 }
1062 else if (RB_TYPE_P(y, T_FLOAT)) {
1063 return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
1064 }
1065 else {
1066 return rb_num_coerce_bin(x, y, '+');
1067 }
1068}
1069
1070/*
1071 * call-seq:
1072 * float - other -> float
1073 *
1074 * Returns a new Float which is the difference of +float+ and +other+.
1075 */
1076
1077 VALUE
1078 rb_float_minus(VALUE x, VALUE y)
1079{
1080 if (RB_TYPE_P(y, T_FIXNUM)) {
1081 return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
1082 }
1083 else if (RB_TYPE_P(y, T_BIGNUM)) {
1084 return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
1085 }
1086 else if (RB_TYPE_P(y, T_FLOAT)) {
1087 return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
1088 }
1089 else {
1090 return rb_num_coerce_bin(x, y, '-');
1091 }
1092}
1093
1094/*
1095 * call-seq:
1096 * float * other -> float
1097 *
1098 * Returns a new Float which is the product of +float+ and +other+.
1099 */
1100
1101 VALUE
1102 rb_float_mul(VALUE x, VALUE y)
1103{
1104 if (RB_TYPE_P(y, T_FIXNUM)) {
1105 return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
1106 }
1107 else if (RB_TYPE_P(y, T_BIGNUM)) {
1108 return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
1109 }
1110 else if (RB_TYPE_P(y, T_FLOAT)) {
1111 return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
1112 }
1113 else {
1114 return rb_num_coerce_bin(x, y, '*');
1115 }
1116}
1117
1118static bool
1119flo_iszero(VALUE f)
1120{
1121 return FLOAT_ZERO_P(f);
1122}
1123
1124static double
1125double_div_double(double x, double y)
1126{
1127 if (LIKELY(y != 0.0)) {
1128 return x / y;
1129 }
1130 else if (x == 0.0) {
1131 return nan("");
1132 }
1133 else {
1134 double z = signbit(y) ? -1.0 : 1.0;
1135 return x * z * HUGE_VAL;
1136 }
1137}
1138
1139 MJIT_FUNC_EXPORTED VALUE
1140 rb_flo_div_flo(VALUE x, VALUE y)
1141{
1142 double num = RFLOAT_VALUE(x);
1143 double den = RFLOAT_VALUE(y);
1144 double ret = double_div_double(num, den);
1145 return DBL2NUM(ret);
1146}
1147
1148/*
1149 * call-seq:
1150 * float / other -> float
1151 *
1152 * Returns a new Float which is the result of dividing +float+ by +other+.
1153 */
1154
1155 VALUE
1156 rb_float_div(VALUE x, VALUE y)
1157{
1158 double num = RFLOAT_VALUE(x);
1159 double den;
1160 double ret;
1161
1162 if (RB_TYPE_P(y, T_FIXNUM)) {
1163 den = FIX2LONG(y);
1164 }
1165 else if (RB_TYPE_P(y, T_BIGNUM)) {
1166 den = rb_big2dbl(y);
1167 }
1168 else if (RB_TYPE_P(y, T_FLOAT)) {
1169 den = RFLOAT_VALUE(y);
1170 }
1171 else {
1172 return rb_num_coerce_bin(x, y, '/');
1173 }
1174
1175 ret = double_div_double(num, den);
1176 return DBL2NUM(ret);
1177}
1178
1179/*
1180 * call-seq:
1181 * float.fdiv(numeric) -> float
1182 * float.quo(numeric) -> float
1183 *
1184 * Returns <code>float / numeric</code>, same as Float#/.
1185 */
1186
1187static VALUE
1188flo_quo(VALUE x, VALUE y)
1189{
1190 return num_funcall1(x, '/', y);
1191}
1192
1193static void
1194flodivmod(double x, double y, double *divp, double *modp)
1195{
1196 double div, mod;
1197
1198 if (isnan(y)) {
1199 /* y is NaN so all results are NaN */
1200 if (modp) *modp = y;
1201 if (divp) *divp = y;
1202 return;
1203 }
1204 if (y == 0.0) rb_num_zerodiv();
1205 if ((x == 0.0) || (isinf(y) && !isinf(x)))
1206 mod = x;
1207 else {
1208#ifdef HAVE_FMOD
1209 mod = fmod(x, y);
1210#else
1211 double z;
1212
1213 modf(x/y, &z);
1214 mod = x - z * y;
1215#endif
1216 }
1217 if (isinf(x) && !isinf(y))
1218 div = x;
1219 else {
1220 div = (x - mod) / y;
1221 if (modp && divp) div = round(div);
1222 }
1223 if (y*mod < 0) {
1224 mod += y;
1225 div -= 1.0;
1226 }
1227 if (modp) *modp = mod;
1228 if (divp) *divp = div;
1229}
1230
1231/*
1232 * Returns the modulo of division of x by y.
1233 * An error will be raised if y == 0.
1234 */
1235
1236 MJIT_FUNC_EXPORTED double
1237 ruby_float_mod(double x, double y)
1238{
1239 double mod;
1240 flodivmod(x, y, 0, &mod);
1241 return mod;
1242}
1243
1244/*
1245 * call-seq:
1246 * float % other -> float
1247 * float.modulo(other) -> float
1248 *
1249 * Returns the modulo after division of +float+ by +other+.
1250 *
1251 * 6543.21.modulo(137) #=> 104.21000000000004
1252 * 6543.21.modulo(137.24) #=> 92.92999999999961
1253 */
1254
1255static VALUE
1256flo_mod(VALUE x, VALUE y)
1257{
1258 double fy;
1259
1260 if (RB_TYPE_P(y, T_FIXNUM)) {
1261 fy = (double)FIX2LONG(y);
1262 }
1263 else if (RB_TYPE_P(y, T_BIGNUM)) {
1264 fy = rb_big2dbl(y);
1265 }
1266 else if (RB_TYPE_P(y, T_FLOAT)) {
1267 fy = RFLOAT_VALUE(y);
1268 }
1269 else {
1270 return rb_num_coerce_bin(x, y, '%');
1271 }
1272 return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
1273}
1274
1275static VALUE
1276dbl2ival(double d)
1277{
1278 if (FIXABLE(d)) {
1279 return LONG2FIX((long)d);
1280 }
1281 return rb_dbl2big(d);
1282}
1283
1284/*
1285 * call-seq:
1286 * float.divmod(numeric) -> array
1287 *
1288 * See Numeric#divmod.
1289 *
1290 * 42.0.divmod(6) #=> [7, 0.0]
1291 * 42.0.divmod(5) #=> [8, 2.0]
1292 */
1293
1294static VALUE
1295flo_divmod(VALUE x, VALUE y)
1296{
1297 double fy, div, mod;
1298 volatile VALUE a, b;
1299
1300 if (RB_TYPE_P(y, T_FIXNUM)) {
1301 fy = (double)FIX2LONG(y);
1302 }
1303 else if (RB_TYPE_P(y, T_BIGNUM)) {
1304 fy = rb_big2dbl(y);
1305 }
1306 else if (RB_TYPE_P(y, T_FLOAT)) {
1307 fy = RFLOAT_VALUE(y);
1308 }
1309 else {
1310 return rb_num_coerce_bin(x, y, id_divmod);
1311 }
1312 flodivmod(RFLOAT_VALUE(x), fy, &div, &mod);
1313 a = dbl2ival(div);
1314 b = DBL2NUM(mod);
1315 return rb_assoc_new(a, b);
1316}
1317
1318/*
1319 * call-seq:
1320 * float ** other -> float
1321 *
1322 * Raises +float+ to the power of +other+.
1323 *
1324 * 2.0**3 #=> 8.0
1325 */
1326
1327 VALUE
1328 rb_float_pow(VALUE x, VALUE y)
1329{
1330 double dx, dy;
1331 if (y == INT2FIX(2)) {
1332 dx = RFLOAT_VALUE(x);
1333 return DBL2NUM(dx * dx);
1334 }
1335 else if (RB_TYPE_P(y, T_FIXNUM)) {
1336 dx = RFLOAT_VALUE(x);
1337 dy = (double)FIX2LONG(y);
1338 }
1339 else if (RB_TYPE_P(y, T_BIGNUM)) {
1340 dx = RFLOAT_VALUE(x);
1341 dy = rb_big2dbl(y);
1342 }
1343 else if (RB_TYPE_P(y, T_FLOAT)) {
1344 dx = RFLOAT_VALUE(x);
1345 dy = RFLOAT_VALUE(y);
1346 if (dx < 0 && dy != round(dy))
1347 return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
1348 }
1349 else {
1350 return rb_num_coerce_bin(x, y, idPow);
1351 }
1352 return DBL2NUM(pow(dx, dy));
1353}
1354
1355/*
1356 * call-seq:
1357 * num.eql?(numeric) -> true or false
1358 *
1359 * Returns +true+ if +num+ and +numeric+ are the same type and have equal
1360 * values. Contrast this with Numeric#==, which performs type conversions.
1361 *
1362 * 1 == 1.0 #=> true
1363 * 1.eql?(1.0) #=> false
1364 * 1.0.eql?(1.0) #=> true
1365 */
1366
1367static VALUE
1368num_eql(VALUE x, VALUE y)
1369{
1370 if (TYPE(x) != TYPE(y)) return Qfalse;
1371
1372 if (RB_TYPE_P(x, T_BIGNUM)) {
1373 return rb_big_eql(x, y);
1374 }
1375
1376 return rb_equal(x, y);
1377}
1378
1379/*
1380 * call-seq:
1381 * number <=> other -> 0 or nil
1382 *
1383 * Returns zero if +number+ equals +other+, otherwise returns +nil+.
1384 */
1385
1386static VALUE
1387num_cmp(VALUE x, VALUE y)
1388{
1389 if (x == y) return INT2FIX(0);
1390 return Qnil;
1391}
1392
1393static VALUE
1394num_equal(VALUE x, VALUE y)
1395{
1396 VALUE result;
1397 if (x == y) return Qtrue;
1398 result = num_funcall1(y, id_eq, x);
1399 if (RTEST(result)) return Qtrue;
1400 return Qfalse;
1401}
1402
1403/*
1404 * call-seq:
1405 * float == obj -> true or false
1406 *
1407 * Returns +true+ only if +obj+ has the same value as +float+.
1408 * Contrast this with Float#eql?, which requires +obj+ to be a Float.
1409 *
1410 * 1.0 == 1 #=> true
1411 *
1412 * The result of <code>NaN == NaN</code> is undefined,
1413 * so an implementation-dependent value is returned.
1414 */
1415
1416 MJIT_FUNC_EXPORTED VALUE
1417 rb_float_equal(VALUE x, VALUE y)
1418{
1419 volatile double a, b;
1420
1421 if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
1422 return rb_integer_float_eq(y, x);
1423 }
1424 else if (RB_TYPE_P(y, T_FLOAT)) {
1425 b = RFLOAT_VALUE(y);
1426#if MSC_VERSION_BEFORE(1300)
1427 if (isnan(b)) return Qfalse;
1428#endif
1429 }
1430 else {
1431 return num_equal(x, y);
1432 }
1433 a = RFLOAT_VALUE(x);
1434#if MSC_VERSION_BEFORE(1300)
1435 if (isnan(a)) return Qfalse;
1436#endif
1437 return (a == b)?Qtrue:Qfalse;
1438}
1439
1440#define flo_eq rb_float_equal
1441static VALUE rb_dbl_hash(double d);
1442
1443/*
1444 * call-seq:
1445 * float.hash -> integer
1446 *
1447 * Returns a hash code for this float.
1448 *
1449 * See also Object#hash.
1450 */
1451
1452static VALUE
1453flo_hash(VALUE num)
1454{
1455 return rb_dbl_hash(RFLOAT_VALUE(num));
1456}
1457
1458static VALUE
1459rb_dbl_hash(double d)
1460{
1461 return ST2FIX(rb_dbl_long_hash(d));
1462}
1463
1464 VALUE
1465 rb_dbl_cmp(double a, double b)
1466{
1467 if (isnan(a) || isnan(b)) return Qnil;
1468 if (a == b) return INT2FIX(0);
1469 if (a > b) return INT2FIX(1);
1470 if (a < b) return INT2FIX(-1);
1471 return Qnil;
1472}
1473
1474/*
1475 * call-seq:
1476 * float <=> real -> -1, 0, +1, or nil
1477 *
1478 * Returns -1, 0, or +1 depending on whether +float+ is
1479 * less than, equal to, or greater than +real+.
1480 * This is the basis for the tests in the Comparable module.
1481 *
1482 * The result of <code>NaN <=> NaN</code> is undefined,
1483 * so an implementation-dependent value is returned.
1484 *
1485 * +nil+ is returned if the two values are incomparable.
1486 */
1487
1488static VALUE
1489flo_cmp(VALUE x, VALUE y)
1490{
1491 double a, b;
1492 VALUE i;
1493
1494 a = RFLOAT_VALUE(x);
1495 if (isnan(a)) return Qnil;
1496 if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
1497 VALUE rel = rb_integer_float_cmp(y, x);
1498 if (FIXNUM_P(rel))
1499 return LONG2FIX(-FIX2LONG(rel));
1500 return rel;
1501 }
1502 else if (RB_TYPE_P(y, T_FLOAT)) {
1503 b = RFLOAT_VALUE(y);
1504 }
1505 else {
1506 if (isinf(a) && (i = rb_check_funcall(y, rb_intern("infinite?"), 0, 0)) != Qundef) {
1507 if (RTEST(i)) {
1508 int j = rb_cmpint(i, x, y);
1509 j = (a > 0.0) ? (j > 0 ? 0 : +1) : (j < 0 ? 0 : -1);
1510 return INT2FIX(j);
1511 }
1512 if (a > 0.0) return INT2FIX(1);
1513 return INT2FIX(-1);
1514 }
1515 return rb_num_coerce_cmp(x, y, id_cmp);
1516 }
1517 return rb_dbl_cmp(a, b);
1518}
1519
1520 MJIT_FUNC_EXPORTED int
1521 rb_float_cmp(VALUE x, VALUE y)
1522{
1523 return NUM2INT(ensure_cmp(flo_cmp(x, y), x, y));
1524}
1525
1526/*
1527 * call-seq:
1528 * float > real -> true or false
1529 *
1530 * Returns +true+ if +float+ is greater than +real+.
1531 *
1532 * The result of <code>NaN > NaN</code> is undefined,
1533 * so an implementation-dependent value is returned.
1534 */
1535
1536 VALUE
1537 rb_float_gt(VALUE x, VALUE y)
1538{
1539 double a, b;
1540
1541 a = RFLOAT_VALUE(x);
1542 if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
1543 VALUE rel = rb_integer_float_cmp(y, x);
1544 if (FIXNUM_P(rel))
1545 return -FIX2LONG(rel) > 0 ? Qtrue : Qfalse;
1546 return Qfalse;
1547 }
1548 else if (RB_TYPE_P(y, T_FLOAT)) {
1549 b = RFLOAT_VALUE(y);
1550#if MSC_VERSION_BEFORE(1300)
1551 if (isnan(b)) return Qfalse;
1552#endif
1553 }
1554 else {
1555 return rb_num_coerce_relop(x, y, '>');
1556 }
1557#if MSC_VERSION_BEFORE(1300)
1558 if (isnan(a)) return Qfalse;
1559#endif
1560 return (a > b)?Qtrue:Qfalse;
1561}
1562
1563/*
1564 * call-seq:
1565 * float >= real -> true or false
1566 *
1567 * Returns +true+ if +float+ is greater than or equal to +real+.
1568 *
1569 * The result of <code>NaN >= NaN</code> is undefined,
1570 * so an implementation-dependent value is returned.
1571 */
1572
1573static VALUE
1574flo_ge(VALUE x, VALUE y)
1575{
1576 double a, b;
1577
1578 a = RFLOAT_VALUE(x);
1579 if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
1580 VALUE rel = rb_integer_float_cmp(y, x);
1581 if (FIXNUM_P(rel))
1582 return -FIX2LONG(rel) >= 0 ? Qtrue : Qfalse;
1583 return Qfalse;
1584 }
1585 else if (RB_TYPE_P(y, T_FLOAT)) {
1586 b = RFLOAT_VALUE(y);
1587#if MSC_VERSION_BEFORE(1300)
1588 if (isnan(b)) return Qfalse;
1589#endif
1590 }
1591 else {
1592 return rb_num_coerce_relop(x, y, idGE);
1593 }
1594#if MSC_VERSION_BEFORE(1300)
1595 if (isnan(a)) return Qfalse;
1596#endif
1597 return (a >= b)?Qtrue:Qfalse;
1598}
1599
1600/*
1601 * call-seq:
1602 * float < real -> true or false
1603 *
1604 * Returns +true+ if +float+ is less than +real+.
1605 *
1606 * The result of <code>NaN < NaN</code> is undefined,
1607 * so an implementation-dependent value is returned.
1608 */
1609
1610static VALUE
1611flo_lt(VALUE x, VALUE y)
1612{
1613 double a, b;
1614
1615 a = RFLOAT_VALUE(x);
1616 if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
1617 VALUE rel = rb_integer_float_cmp(y, x);
1618 if (FIXNUM_P(rel))
1619 return -FIX2LONG(rel) < 0 ? Qtrue : Qfalse;
1620 return Qfalse;
1621 }
1622 else if (RB_TYPE_P(y, T_FLOAT)) {
1623 b = RFLOAT_VALUE(y);
1624#if MSC_VERSION_BEFORE(1300)
1625 if (isnan(b)) return Qfalse;
1626#endif
1627 }
1628 else {
1629 return rb_num_coerce_relop(x, y, '<');
1630 }
1631#if MSC_VERSION_BEFORE(1300)
1632 if (isnan(a)) return Qfalse;
1633#endif
1634 return (a < b)?Qtrue:Qfalse;
1635}
1636
1637/*
1638 * call-seq:
1639 * float <= real -> true or false
1640 *
1641 * Returns +true+ if +float+ is less than or equal to +real+.
1642 *
1643 * The result of <code>NaN <= NaN</code> is undefined,
1644 * so an implementation-dependent value is returned.
1645 */
1646
1647static VALUE
1648flo_le(VALUE x, VALUE y)
1649{
1650 double a, b;
1651
1652 a = RFLOAT_VALUE(x);
1653 if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
1654 VALUE rel = rb_integer_float_cmp(y, x);
1655 if (FIXNUM_P(rel))
1656 return -FIX2LONG(rel) <= 0 ? Qtrue : Qfalse;
1657 return Qfalse;
1658 }
1659 else if (RB_TYPE_P(y, T_FLOAT)) {
1660 b = RFLOAT_VALUE(y);
1661#if MSC_VERSION_BEFORE(1300)
1662 if (isnan(b)) return Qfalse;
1663#endif
1664 }
1665 else {
1666 return rb_num_coerce_relop(x, y, idLE);
1667 }
1668#if MSC_VERSION_BEFORE(1300)
1669 if (isnan(a)) return Qfalse;
1670#endif
1671 return (a <= b)?Qtrue:Qfalse;
1672}
1673
1674/*
1675 * call-seq:
1676 * float.eql?(obj) -> true or false
1677 *
1678 * Returns +true+ only if +obj+ is a Float with the same value as +float+.
1679 * Contrast this with Float#==, which performs type conversions.
1680 *
1681 * 1.0.eql?(1) #=> false
1682 *
1683 * The result of <code>NaN.eql?(NaN)</code> is undefined,
1684 * so an implementation-dependent value is returned.
1685 */
1686
1687 MJIT_FUNC_EXPORTED VALUE
1688 rb_float_eql(VALUE x, VALUE y)
1689{
1690 if (RB_TYPE_P(y, T_FLOAT)) {
1691 double a = RFLOAT_VALUE(x);
1692 double b = RFLOAT_VALUE(y);
1693#if MSC_VERSION_BEFORE(1300)
1694 if (isnan(a) || isnan(b)) return Qfalse;
1695#endif
1696 if (a == b)
1697 return Qtrue;
1698 }
1699 return Qfalse;
1700}
1701
1702#define flo_eql rb_float_eql
1703
1704/*
1705 * call-seq:
1706 * float.to_f -> self
1707 *
1708 * Since +float+ is already a Float, returns +self+.
1709 */
1710
1711static VALUE
1712flo_to_f(VALUE num)
1713{
1714 return num;
1715}
1716
1717/*
1718 * call-seq:
1719 * float.abs -> float
1720 * float.magnitude -> float
1721 *
1722 * Returns the absolute value of +float+.
1723 *
1724 * (-34.56).abs #=> 34.56
1725 * -34.56.abs #=> 34.56
1726 * 34.56.abs #=> 34.56
1727 *
1728 * Float#magnitude is an alias for Float#abs.
1729 */
1730
1731 VALUE
1732 rb_float_abs(VALUE flt)
1733{
1734 double val = fabs(RFLOAT_VALUE(flt));
1735 return DBL2NUM(val);
1736}
1737
1738/*
1739 * call-seq:
1740 * float.zero? -> true or false
1741 *
1742 * Returns +true+ if +float+ is 0.0.
1743 */
1744
1745static VALUE
1746flo_zero_p(VALUE num)
1747{
1748 return flo_iszero(num) ? Qtrue : Qfalse;
1749}
1750
1751/*
1752 * call-seq:
1753 * float.nan? -> true or false
1754 *
1755 * Returns +true+ if +float+ is an invalid IEEE floating point number.
1756 *
1757 * a = -1.0 #=> -1.0
1758 * a.nan? #=> false
1759 * a = 0.0/0.0 #=> NaN
1760 * a.nan? #=> true
1761 */
1762
1763static VALUE
1764flo_is_nan_p(VALUE num)
1765{
1766 double value = RFLOAT_VALUE(num);
1767
1768 return isnan(value) ? Qtrue : Qfalse;
1769}
1770
1771/*
1772 * call-seq:
1773 * float.infinite? -> -1, 1, or nil
1774 *
1775 * Returns +nil+, -1, or 1 depending on whether the value is
1776 * finite, <code>-Infinity</code>, or <code>+Infinity</code>.
1777 *
1778 * (0.0).infinite? #=> nil
1779 * (-1.0/0.0).infinite? #=> -1
1780 * (+1.0/0.0).infinite? #=> 1
1781 */
1782
1783 VALUE
1784 rb_flo_is_infinite_p(VALUE num)
1785{
1786 double value = RFLOAT_VALUE(num);
1787
1788 if (isinf(value)) {
1789 return INT2FIX( value < 0 ? -1 : 1 );
1790 }
1791
1792 return Qnil;
1793}
1794
1795/*
1796 * call-seq:
1797 * float.finite? -> true or false
1798 *
1799 * Returns +true+ if +float+ is a valid IEEE floating point number,
1800 * i.e. it is not infinite and Float#nan? is +false+.
1801 */
1802
1803 VALUE
1804 rb_flo_is_finite_p(VALUE num)
1805{
1806 double value = RFLOAT_VALUE(num);
1807
1808#ifdef HAVE_ISFINITE
1809 if (!isfinite(value))
1810 return Qfalse;
1811#else
1812 if (isinf(value) || isnan(value))
1813 return Qfalse;
1814#endif
1815
1816 return Qtrue;
1817}
1818
1819static VALUE
1820flo_nextafter(VALUE flo, double value)
1821{
1822 double x, y;
1823 x = NUM2DBL(flo);
1824 y = nextafter(x, value);
1825 return DBL2NUM(y);
1826}
1827
1828/*
1829 * call-seq:
1830 * float.next_float -> float
1831 *
1832 * Returns the next representable floating point number.
1833 *
1834 * Float::MAX.next_float and Float::INFINITY.next_float is Float::INFINITY.
1835 *
1836 * Float::NAN.next_float is Float::NAN.
1837 *
1838 * For example:
1839 *
1840 * 0.01.next_float #=> 0.010000000000000002
1841 * 1.0.next_float #=> 1.0000000000000002
1842 * 100.0.next_float #=> 100.00000000000001
1843 *
1844 * 0.01.next_float - 0.01 #=> 1.734723475976807e-18
1845 * 1.0.next_float - 1.0 #=> 2.220446049250313e-16
1846 * 100.0.next_float - 100.0 #=> 1.4210854715202004e-14
1847 *
1848 * f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.next_float }
1849 * #=> 0x1.47ae147ae147bp-7 0.01
1850 * # 0x1.47ae147ae147cp-7 0.010000000000000002
1851 * # 0x1.47ae147ae147dp-7 0.010000000000000004
1852 * # 0x1.47ae147ae147ep-7 0.010000000000000005
1853 * # 0x1.47ae147ae147fp-7 0.010000000000000007
1854 * # 0x1.47ae147ae148p-7 0.010000000000000009
1855 * # 0x1.47ae147ae1481p-7 0.01000000000000001
1856 * # 0x1.47ae147ae1482p-7 0.010000000000000012
1857 * # 0x1.47ae147ae1483p-7 0.010000000000000014
1858 * # 0x1.47ae147ae1484p-7 0.010000000000000016
1859 * # 0x1.47ae147ae1485p-7 0.010000000000000018
1860 * # 0x1.47ae147ae1486p-7 0.01000000000000002
1861 * # 0x1.47ae147ae1487p-7 0.010000000000000021
1862 * # 0x1.47ae147ae1488p-7 0.010000000000000023
1863 * # 0x1.47ae147ae1489p-7 0.010000000000000024
1864 * # 0x1.47ae147ae148ap-7 0.010000000000000026
1865 * # 0x1.47ae147ae148bp-7 0.010000000000000028
1866 * # 0x1.47ae147ae148cp-7 0.01000000000000003
1867 * # 0x1.47ae147ae148dp-7 0.010000000000000031
1868 * # 0x1.47ae147ae148ep-7 0.010000000000000033
1869 *
1870 * f = 0.0
1871 * 100.times { f += 0.1 }
1872 * f #=> 9.99999999999998 # should be 10.0 in the ideal world.
1873 * 10-f #=> 1.9539925233402755e-14 # the floating point error.
1874 * 10.0.next_float-10 #=> 1.7763568394002505e-15 # 1 ulp (unit in the last place).
1875 * (10-f)/(10.0.next_float-10) #=> 11.0 # the error is 11 ulp.
1876 * (10-f)/(10*Float::EPSILON) #=> 8.8 # approximation of the above.
1877 * "%a" % 10 #=> "0x1.4p+3"
1878 * "%a" % f #=> "0x1.3fffffffffff5p+3" # the last hex digit is 5. 16 - 5 = 11 ulp.
1879 */
1880static VALUE
1881flo_next_float(VALUE vx)
1882{
1883 return flo_nextafter(vx, HUGE_VAL);
1884}
1885
1886/*
1887 * call-seq:
1888 * float.prev_float -> float
1889 *
1890 * Returns the previous representable floating point number.
1891 *
1892 * (-Float::MAX).prev_float and (-Float::INFINITY).prev_float is -Float::INFINITY.
1893 *
1894 * Float::NAN.prev_float is Float::NAN.
1895 *
1896 * For example:
1897 *
1898 * 0.01.prev_float #=> 0.009999999999999998
1899 * 1.0.prev_float #=> 0.9999999999999999
1900 * 100.0.prev_float #=> 99.99999999999999
1901 *
1902 * 0.01 - 0.01.prev_float #=> 1.734723475976807e-18
1903 * 1.0 - 1.0.prev_float #=> 1.1102230246251565e-16
1904 * 100.0 - 100.0.prev_float #=> 1.4210854715202004e-14
1905 *
1906 * f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.prev_float }
1907 * #=> 0x1.47ae147ae147bp-7 0.01
1908 * # 0x1.47ae147ae147ap-7 0.009999999999999998
1909 * # 0x1.47ae147ae1479p-7 0.009999999999999997
1910 * # 0x1.47ae147ae1478p-7 0.009999999999999995
1911 * # 0x1.47ae147ae1477p-7 0.009999999999999993
1912 * # 0x1.47ae147ae1476p-7 0.009999999999999992
1913 * # 0x1.47ae147ae1475p-7 0.00999999999999999
1914 * # 0x1.47ae147ae1474p-7 0.009999999999999988
1915 * # 0x1.47ae147ae1473p-7 0.009999999999999986
1916 * # 0x1.47ae147ae1472p-7 0.009999999999999985
1917 * # 0x1.47ae147ae1471p-7 0.009999999999999983
1918 * # 0x1.47ae147ae147p-7 0.009999999999999981
1919 * # 0x1.47ae147ae146fp-7 0.00999999999999998
1920 * # 0x1.47ae147ae146ep-7 0.009999999999999978
1921 * # 0x1.47ae147ae146dp-7 0.009999999999999976
1922 * # 0x1.47ae147ae146cp-7 0.009999999999999974
1923 * # 0x1.47ae147ae146bp-7 0.009999999999999972
1924 * # 0x1.47ae147ae146ap-7 0.00999999999999997
1925 * # 0x1.47ae147ae1469p-7 0.009999999999999969
1926 * # 0x1.47ae147ae1468p-7 0.009999999999999967
1927 */
1928static VALUE
1929flo_prev_float(VALUE vx)
1930{
1931 return flo_nextafter(vx, -HUGE_VAL);
1932}
1933
1934 VALUE
1935 rb_float_floor(VALUE num, int ndigits)
1936{
1937 double number, f;
1938 number = RFLOAT_VALUE(num);
1939 if (number == 0.0) {
1940 return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
1941 }
1942 if (ndigits > 0) {
1943 int binexp;
1944 frexp(number, &binexp);
1945 if (float_round_overflow(ndigits, binexp)) return num;
1946 if (number > 0.0 && float_round_underflow(ndigits, binexp))
1947 return DBL2NUM(0.0);
1948 f = pow(10, ndigits);
1949 f = floor(number * f) / f;
1950 return DBL2NUM(f);
1951 }
1952 else {
1953 num = dbl2ival(floor(number));
1954 if (ndigits < 0) num = rb_int_floor(num, ndigits);
1955 return num;
1956 }
1957}
1958
1959/*
1960 * call-seq:
1961 * float.floor([ndigits]) -> integer or float
1962 *
1963 * Returns the largest number less than or equal to +float+ with
1964 * a precision of +ndigits+ decimal digits (default: 0).
1965 *
1966 * When the precision is negative, the returned value is an integer
1967 * with at least <code>ndigits.abs</code> trailing zeros.
1968 *
1969 * Returns a floating point number when +ndigits+ is positive,
1970 * otherwise returns an integer.
1971 *
1972 * 1.2.floor #=> 1
1973 * 2.0.floor #=> 2
1974 * (-1.2).floor #=> -2
1975 * (-2.0).floor #=> -2
1976 *
1977 * 1.234567.floor(2) #=> 1.23
1978 * 1.234567.floor(3) #=> 1.234
1979 * 1.234567.floor(4) #=> 1.2345
1980 * 1.234567.floor(5) #=> 1.23456
1981 *
1982 * 34567.89.floor(-5) #=> 0
1983 * 34567.89.floor(-4) #=> 30000
1984 * 34567.89.floor(-3) #=> 34000
1985 * 34567.89.floor(-2) #=> 34500
1986 * 34567.89.floor(-1) #=> 34560
1987 * 34567.89.floor(0) #=> 34567
1988 * 34567.89.floor(1) #=> 34567.8
1989 * 34567.89.floor(2) #=> 34567.89
1990 * 34567.89.floor(3) #=> 34567.89
1991 *
1992 * Note that the limited precision of floating point arithmetic
1993 * might lead to surprising results:
1994 *
1995 * (0.3 / 0.1).floor #=> 2 (!)
1996 */
1997
1998static VALUE
1999flo_floor(int argc, VALUE *argv, VALUE num)
2000{
2001 int ndigits = 0;
2002 if (rb_check_arity(argc, 0, 1)) {
2003 ndigits = NUM2INT(argv[0]);
2004 }
2005 return rb_float_floor(num, ndigits);
2006}
2007
2008/*
2009 * call-seq:
2010 * float.ceil([ndigits]) -> integer or float
2011 *
2012 * Returns the smallest number greater than or equal to +float+ with
2013 * a precision of +ndigits+ decimal digits (default: 0).
2014 *
2015 * When the precision is negative, the returned value is an integer
2016 * with at least <code>ndigits.abs</code> trailing zeros.
2017 *
2018 * Returns a floating point number when +ndigits+ is positive,
2019 * otherwise returns an integer.
2020 *
2021 * 1.2.ceil #=> 2
2022 * 2.0.ceil #=> 2
2023 * (-1.2).ceil #=> -1
2024 * (-2.0).ceil #=> -2
2025 *
2026 * 1.234567.ceil(2) #=> 1.24
2027 * 1.234567.ceil(3) #=> 1.235
2028 * 1.234567.ceil(4) #=> 1.2346
2029 * 1.234567.ceil(5) #=> 1.23457
2030 *
2031 * 34567.89.ceil(-5) #=> 100000
2032 * 34567.89.ceil(-4) #=> 40000
2033 * 34567.89.ceil(-3) #=> 35000
2034 * 34567.89.ceil(-2) #=> 34600
2035 * 34567.89.ceil(-1) #=> 34570
2036 * 34567.89.ceil(0) #=> 34568
2037 * 34567.89.ceil(1) #=> 34567.9
2038 * 34567.89.ceil(2) #=> 34567.89
2039 * 34567.89.ceil(3) #=> 34567.89
2040 *
2041 * Note that the limited precision of floating point arithmetic
2042 * might lead to surprising results:
2043 *
2044 * (2.1 / 0.7).ceil #=> 4 (!)
2045 */
2046
2047static VALUE
2048flo_ceil(int argc, VALUE *argv, VALUE num)
2049{
2050 int ndigits = 0;
2051
2052 if (rb_check_arity(argc, 0, 1)) {
2053 ndigits = NUM2INT(argv[0]);
2054 }
2055 return rb_float_ceil(num, ndigits);
2056}
2057
2058 VALUE
2059 rb_float_ceil(VALUE num, int ndigits)
2060{
2061 double number, f;
2062
2063 number = RFLOAT_VALUE(num);
2064 if (number == 0.0) {
2065 return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
2066 }
2067 if (ndigits > 0) {
2068 int binexp;
2069 frexp(number, &binexp);
2070 if (float_round_overflow(ndigits, binexp)) return num;
2071 if (number < 0.0 && float_round_underflow(ndigits, binexp))
2072 return DBL2NUM(0.0);
2073 f = pow(10, ndigits);
2074 f = ceil(number * f) / f;
2075 return DBL2NUM(f);
2076 }
2077 else {
2078 num = dbl2ival(ceil(number));
2079 if (ndigits < 0) num = rb_int_ceil(num, ndigits);
2080 return num;
2081 }
2082}
2083
2084static int
2085int_round_zero_p(VALUE num, int ndigits)
2086{
2087 long bytes;
2088 /* If 10**N / 2 > num, then return 0 */
2089 /* We have log_256(10) > 0.415241 and log_256(1/2) = -0.125, so */
2090 if (FIXNUM_P(num)) {
2091 bytes = sizeof(long);
2092 }
2093 else if (RB_TYPE_P(num, T_BIGNUM)) {
2094 bytes = rb_big_size(num);
2095 }
2096 else {
2097 bytes = NUM2LONG(rb_funcall(num, idSize, 0));
2098 }
2099 return (-0.415241 * ndigits - 0.125 > bytes);
2100}
2101
2102static SIGNED_VALUE
2103int_round_half_even(SIGNED_VALUE x, SIGNED_VALUE y)
2104{
2105 SIGNED_VALUE z = +(x + y / 2) / y;
2106 if ((z * y - x) * 2 == y) {
2107 z &= ~1;
2108 }
2109 return z * y;
2110}
2111
2112static SIGNED_VALUE
2113int_round_half_up(SIGNED_VALUE x, SIGNED_VALUE y)
2114{
2115 return (x + y / 2) / y * y;
2116}
2117
2118static SIGNED_VALUE
2119int_round_half_down(SIGNED_VALUE x, SIGNED_VALUE y)
2120{
2121 return (x + y / 2 - 1) / y * y;
2122}
2123
2124static int
2125int_half_p_half_even(VALUE num, VALUE n, VALUE f)
2126{
2127 return (int)rb_int_odd_p(rb_int_idiv(n, f));
2128}
2129
2130static int
2131int_half_p_half_up(VALUE num, VALUE n, VALUE f)
2132{
2133 return int_pos_p(num);
2134}
2135
2136static int
2137int_half_p_half_down(VALUE num, VALUE n, VALUE f)
2138{
2139 return int_neg_p(num);
2140}
2141
2142/*
2143 * Assumes num is an Integer, ndigits <= 0
2144 */
2145static VALUE
2146rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode)
2147{
2148 VALUE n, f, h, r;
2149
2150 if (int_round_zero_p(num, ndigits)) {
2151 return INT2FIX(0);
2152 }
2153
2154 f = int_pow(10, -ndigits);
2155 if (FIXNUM_P(num) && FIXNUM_P(f)) {
2156 SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
2157 int neg = x < 0;
2158 if (neg) x = -x;
2159 x = ROUND_CALL(mode, int_round, (x, y));
2160 if (neg) x = -x;
2161 return LONG2NUM(x);
2162 }
2163 if (RB_TYPE_P(f, T_FLOAT)) {
2164 /* then int_pow overflow */
2165 return INT2FIX(0);
2166 }
2167 h = rb_int_idiv(f, INT2FIX(2));
2168 r = rb_int_modulo(num, f);
2169 n = rb_int_minus(num, r);
2170 r = rb_int_cmp(r, h);
2171 if (FIXNUM_POSITIVE_P(r) ||
2172 (FIXNUM_ZERO_P(r) && ROUND_CALL(mode, int_half_p, (num, n, f)))) {
2173 n = rb_int_plus(n, f);
2174 }
2175 return n;
2176}
2177
2178static VALUE
2179rb_int_floor(VALUE num, int ndigits)
2180{
2181 VALUE f;
2182
2183 if (int_round_zero_p(num, ndigits))
2184 return INT2FIX(0);
2185 f = int_pow(10, -ndigits);
2186 if (FIXNUM_P(num) && FIXNUM_P(f)) {
2187 SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
2188 int neg = x < 0;
2189 if (neg) x = -x + y - 1;
2190 x = x / y * y;
2191 if (neg) x = -x;
2192 return LONG2NUM(x);
2193 }
2194 if (RB_TYPE_P(f, T_FLOAT)) {
2195 /* then int_pow overflow */
2196 return INT2FIX(0);
2197 }
2198 return rb_int_minus(num, rb_int_modulo(num, f));
2199}
2200
2201static VALUE
2202rb_int_ceil(VALUE num, int ndigits)
2203{
2204 VALUE f;
2205
2206 if (int_round_zero_p(num, ndigits))
2207 return INT2FIX(0);
2208 f = int_pow(10, -ndigits);
2209 if (FIXNUM_P(num) && FIXNUM_P(f)) {
2210 SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
2211 int neg = x < 0;
2212 if (neg) x = -x;
2213 else x += y - 1;
2214 x = (x / y) * y;
2215 if (neg) x = -x;
2216 return LONG2NUM(x);
2217 }
2218 if (RB_TYPE_P(f, T_FLOAT)) {
2219 /* then int_pow overflow */
2220 return INT2FIX(0);
2221 }
2222 return rb_int_plus(num, rb_int_minus(f, rb_int_modulo(num, f)));
2223}
2224
2225 VALUE
2226rb_int_truncate(VALUE num, int ndigits)
2227{
2228 VALUE f;
2229 VALUE m;
2230
2231 if (int_round_zero_p(num, ndigits))
2232 return INT2FIX(0);
2233 f = int_pow(10, -ndigits);
2234 if (FIXNUM_P(num) && FIXNUM_P(f)) {
2235 SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
2236 int neg = x < 0;
2237 if (neg) x = -x;
2238 x = x / y * y;
2239 if (neg) x = -x;
2240 return LONG2NUM(x);
2241 }
2242 if (RB_TYPE_P(f, T_FLOAT)) {
2243 /* then int_pow overflow */
2244 return INT2FIX(0);
2245 }
2246 m = rb_int_modulo(num, f);
2247 if (int_neg_p(num)) {
2248 return rb_int_plus(num, rb_int_minus(f, m));
2249 }
2250 else {
2251 return rb_int_minus(num, m);
2252 }
2253}
2254
2255/*
2256 * call-seq:
2257 * float.round([ndigits] [, half: mode]) -> integer or float
2258 *
2259 * Returns +float+ rounded to the nearest value with
2260 * a precision of +ndigits+ decimal digits (default: 0).
2261 *
2262 * When the precision is negative, the returned value is an integer
2263 * with at least <code>ndigits.abs</code> trailing zeros.
2264 *
2265 * Returns a floating point number when +ndigits+ is positive,
2266 * otherwise returns an integer.
2267 *
2268 * 1.4.round #=> 1
2269 * 1.5.round #=> 2
2270 * 1.6.round #=> 2
2271 * (-1.5).round #=> -2
2272 *
2273 * 1.234567.round(2) #=> 1.23
2274 * 1.234567.round(3) #=> 1.235
2275 * 1.234567.round(4) #=> 1.2346
2276 * 1.234567.round(5) #=> 1.23457
2277 *
2278 * 34567.89.round(-5) #=> 0
2279 * 34567.89.round(-4) #=> 30000
2280 * 34567.89.round(-3) #=> 35000
2281 * 34567.89.round(-2) #=> 34600
2282 * 34567.89.round(-1) #=> 34570
2283 * 34567.89.round(0) #=> 34568
2284 * 34567.89.round(1) #=> 34567.9
2285 * 34567.89.round(2) #=> 34567.89
2286 * 34567.89.round(3) #=> 34567.89
2287 *
2288 * If the optional +half+ keyword argument is given,
2289 * numbers that are half-way between two possible rounded values
2290 * will be rounded according to the specified tie-breaking +mode+:
2291 *
2292 * * <code>:up</code> or +nil+: round half away from zero (default)
2293 * * <code>:down</code>: round half toward zero
2294 * * <code>:even</code>: round half toward the nearest even number
2295 *
2296 * 2.5.round(half: :up) #=> 3
2297 * 2.5.round(half: :down) #=> 2
2298 * 2.5.round(half: :even) #=> 2
2299 * 3.5.round(half: :up) #=> 4
2300 * 3.5.round(half: :down) #=> 3
2301 * 3.5.round(half: :even) #=> 4
2302 * (-2.5).round(half: :up) #=> -3
2303 * (-2.5).round(half: :down) #=> -2
2304 * (-2.5).round(half: :even) #=> -2
2305 */
2306
2307static VALUE
2308flo_round(int argc, VALUE *argv, VALUE num)
2309{
2310 double number, f, x;
2311 VALUE nd, opt;
2312 int ndigits = 0;
2313 enum ruby_num_rounding_mode mode;
2314
2315 if (rb_scan_args(argc, argv, "01:", &nd, &opt)) {
2316 ndigits = NUM2INT(nd);
2317 }
2318 mode = rb_num_get_rounding_option(opt);
2319 number = RFLOAT_VALUE(num);
2320 if (number == 0.0) {
2321 return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
2322 }
2323 if (ndigits < 0) {
2324 return rb_int_round(flo_to_i(num), ndigits, mode);
2325 }
2326 if (ndigits == 0) {
2327 x = ROUND_CALL(mode, round, (number, 1.0));
2328 return dbl2ival(x);
2329 }
2330 if (isfinite(number)) {
2331 int binexp;
2332 frexp(number, &binexp);
2333 if (float_round_overflow(ndigits, binexp)) return num;
2334 if (float_round_underflow(ndigits, binexp)) return DBL2NUM(0);
2335 f = pow(10, ndigits);
2336 x = ROUND_CALL(mode, round, (number, f));
2337 return DBL2NUM(x / f);
2338 }
2339 return num;
2340}
2341
2342static int
2343float_round_overflow(int ndigits, int binexp)
2344{
2345 enum {float_dig = DBL_DIG+2};
2346
2347/* Let `exp` be such that `number` is written as:"0.#{digits}e#{exp}",
2348 i.e. such that 10 ** (exp - 1) <= |number| < 10 ** exp
2349 Recall that up to float_dig digits can be needed to represent a double,
2350 so if ndigits + exp >= float_dig, the intermediate value (number * 10 ** ndigits)
2351 will be an integer and thus the result is the original number.
2352 If ndigits + exp <= 0, the result is 0 or "1e#{exp}", so
2353 if ndigits + exp < 0, the result is 0.
2354 We have:
2355 2 ** (binexp-1) <= |number| < 2 ** binexp
2356 10 ** ((binexp-1)/log_2(10)) <= |number| < 10 ** (binexp/log_2(10))
2357 If binexp >= 0, and since log_2(10) = 3.322259:
2358 10 ** (binexp/4 - 1) < |number| < 10 ** (binexp/3)
2359 floor(binexp/4) <= exp <= ceil(binexp/3)
2360 If binexp <= 0, swap the /4 and the /3
2361 So if ndigits + floor(binexp/(4 or 3)) >= float_dig, the result is number
2362 If ndigits + ceil(binexp/(3 or 4)) < 0 the result is 0
2363*/
2364 if (ndigits >= float_dig - (binexp > 0 ? binexp / 4 : binexp / 3 - 1)) {
2365 return TRUE;
2366 }
2367 return FALSE;
2368}
2369
2370static int
2371float_round_underflow(int ndigits, int binexp)
2372{
2373 if (ndigits < - (binexp > 0 ? binexp / 3 + 1 : binexp / 4)) {
2374 return TRUE;
2375 }
2376 return FALSE;
2377}
2378
2379/*
2380 * call-seq:
2381 * float.to_i -> integer
2382 * float.to_int -> integer
2383 *
2384 * Returns the +float+ truncated to an Integer.
2385 *
2386 * 1.2.to_i #=> 1
2387 * (-1.2).to_i #=> -1
2388 *
2389 * Note that the limited precision of floating point arithmetic
2390 * might lead to surprising results:
2391 *
2392 * (0.3 / 0.1).to_i #=> 2 (!)
2393 *
2394 * #to_int is an alias for #to_i.
2395 */
2396
2397static VALUE
2398flo_to_i(VALUE num)
2399{
2400 double f = RFLOAT_VALUE(num);
2401
2402 if (f > 0.0) f = floor(f);
2403 if (f < 0.0) f = ceil(f);
2404
2405 return dbl2ival(f);
2406}
2407
2408/*
2409 * call-seq:
2410 * float.truncate([ndigits]) -> integer or float
2411 *
2412 * Returns +float+ truncated (toward zero) to
2413 * a precision of +ndigits+ decimal digits (default: 0).
2414 *
2415 * When the precision is negative, the returned value is an integer
2416 * with at least <code>ndigits.abs</code> trailing zeros.
2417 *
2418 * Returns a floating point number when +ndigits+ is positive,
2419 * otherwise returns an integer.
2420 *
2421 * 2.8.truncate #=> 2
2422 * (-2.8).truncate #=> -2
2423 * 1.234567.truncate(2) #=> 1.23
2424 * 34567.89.truncate(-2) #=> 34500
2425 *
2426 * Note that the limited precision of floating point arithmetic
2427 * might lead to surprising results:
2428 *
2429 * (0.3 / 0.1).truncate #=> 2 (!)
2430 */
2431static VALUE
2432flo_truncate(int argc, VALUE *argv, VALUE num)
2433{
2434 if (signbit(RFLOAT_VALUE(num)))
2435 return flo_ceil(argc, argv, num);
2436 else
2437 return flo_floor(argc, argv, num);
2438}
2439
2440/*
2441 * call-seq:
2442 * float.positive? -> true or false
2443 *
2444 * Returns +true+ if +float+ is greater than 0.
2445 */
2446
2447static VALUE
2448flo_positive_p(VALUE num)
2449{
2450 double f = RFLOAT_VALUE(num);
2451 return f > 0.0 ? Qtrue : Qfalse;
2452}
2453
2454/*
2455 * call-seq:
2456 * float.negative? -> true or false
2457 *
2458 * Returns +true+ if +float+ is less than 0.
2459 */
2460
2461static VALUE
2462flo_negative_p(VALUE num)
2463{
2464 double f = RFLOAT_VALUE(num);
2465 return f < 0.0 ? Qtrue : Qfalse;
2466}
2467
2468/*
2469 * call-seq:
2470 * num.floor([ndigits]) -> integer or float
2471 *
2472 * Returns the largest number less than or equal to +num+ with
2473 * a precision of +ndigits+ decimal digits (default: 0).
2474 *
2475 * Numeric implements this by converting its value to a Float and
2476 * invoking Float#floor.
2477 */
2478
2479static VALUE
2480num_floor(int argc, VALUE *argv, VALUE num)
2481{
2482 return flo_floor(argc, argv, rb_Float(num));
2483}
2484
2485/*
2486 * call-seq:
2487 * num.ceil([ndigits]) -> integer or float
2488 *
2489 * Returns the smallest number greater than or equal to +num+ with
2490 * a precision of +ndigits+ decimal digits (default: 0).
2491 *
2492 * Numeric implements this by converting its value to a Float and
2493 * invoking Float#ceil.
2494 */
2495
2496static VALUE
2497num_ceil(int argc, VALUE *argv, VALUE num)
2498{
2499 return flo_ceil(argc, argv, rb_Float(num));
2500}
2501
2502/*
2503 * call-seq:
2504 * num.round([ndigits]) -> integer or float
2505 *
2506 * Returns +num+ rounded to the nearest value with
2507 * a precision of +ndigits+ decimal digits (default: 0).
2508 *
2509 * Numeric implements this by converting its value to a Float and
2510 * invoking Float#round.
2511 */
2512
2513static VALUE
2514num_round(int argc, VALUE* argv, VALUE num)
2515{
2516 return flo_round(argc, argv, rb_Float(num));
2517}
2518
2519/*
2520 * call-seq:
2521 * num.truncate([ndigits]) -> integer or float
2522 *
2523 * Returns +num+ truncated (toward zero) to
2524 * a precision of +ndigits+ decimal digits (default: 0).
2525 *
2526 * Numeric implements this by converting its value to a Float and
2527 * invoking Float#truncate.
2528 */
2529
2530static VALUE
2531num_truncate(int argc, VALUE *argv, VALUE num)
2532{
2533 return flo_truncate(argc, argv, rb_Float(num));
2534}
2535
2536double
2537 ruby_float_step_size(double beg, double end, double unit, int excl)
2538{
2539 const double epsilon = DBL_EPSILON;
2540 double n, err;
2541
2542 if (unit == 0) {
2543 return HUGE_VAL;
2544 }
2545 n= (end - beg)/unit;
2546 err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
2547 if (isinf(unit)) {
2548 return unit > 0 ? beg <= end : beg >= end;
2549 }
2550 if (err>0.5) err=0.5;
2551 if (excl) {
2552 if (n<=0) return 0;
2553 if (n<1)
2554 n = 0;
2555 else
2556 n = floor(n - err);
2557 }
2558 else {
2559 if (n<0) return 0;
2560 n = floor(n + err);
2561 }
2562 return n+1;
2563}
2564
2565int
2566 ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless)
2567{
2568 if (RB_TYPE_P(from, T_FLOAT) || RB_TYPE_P(to, T_FLOAT) || RB_TYPE_P(step, T_FLOAT)) {
2569 double unit = NUM2DBL(step);
2570 double beg = NUM2DBL(from);
2571 double end = (allow_endless && NIL_P(to)) ? (unit < 0 ? -1 : 1)*HUGE_VAL : NUM2DBL(to);
2572 double n = ruby_float_step_size(beg, end, unit, excl);
2573 long i;
2574
2575 if (isinf(unit)) {
2576 /* if unit is infinity, i*unit+beg is NaN */
2577 if (n) rb_yield(DBL2NUM(beg));
2578 }
2579 else if (unit == 0) {
2580 VALUE val = DBL2NUM(beg);
2581 for (;;)
2582 rb_yield(val);
2583 }
2584 else {
2585 for (i=0; i<n; i++) {
2586 double d = i*unit+beg;
2587 if (unit >= 0 ? end < d : d < end) d = end;
2588 rb_yield(DBL2NUM(d));
2589 }
2590 }
2591 return TRUE;
2592 }
2593 return FALSE;
2594}
2595
2596 VALUE
2597 ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
2598{
2599 if (FIXNUM_P(from) && FIXNUM_P(to) && FIXNUM_P(step)) {
2600 long delta, diff;
2601
2602 diff = FIX2LONG(step);
2603 if (diff == 0) {
2604 return DBL2NUM(HUGE_VAL);
2605 }
2606 delta = FIX2LONG(to) - FIX2LONG(from);
2607 if (diff < 0) {
2608 diff = -diff;
2609 delta = -delta;
2610 }
2611 if (excl) {
2612 delta--;
2613 }
2614 if (delta < 0) {
2615 return INT2FIX(0);
2616 }
2617 return ULONG2NUM(delta / diff + 1UL);
2618 }
2619 else if (RB_TYPE_P(from, T_FLOAT) || RB_TYPE_P(to, T_FLOAT) || RB_TYPE_P(step, T_FLOAT)) {
2620 double n = ruby_float_step_size(NUM2DBL(from), NUM2DBL(to), NUM2DBL(step), excl);
2621
2622 if (isinf(n)) return DBL2NUM(n);
2623 if (POSFIXABLE(n)) return LONG2FIX((long)n);
2624 return rb_dbl2big(n);
2625 }
2626 else {
2627 VALUE result;
2628 ID cmp = '>';
2629 switch (rb_cmpint(rb_num_coerce_cmp(step, INT2FIX(0), id_cmp), step, INT2FIX(0))) {
2630 case 0: return DBL2NUM(HUGE_VAL);
2631 case -1: cmp = '<'; break;
2632 }
2633 if (RTEST(rb_funcall(from, cmp, 1, to))) return INT2FIX(0);
2634 result = rb_funcall(rb_funcall(to, '-', 1, from), id_div, 1, step);
2635 if (!excl || RTEST(rb_funcall(rb_funcall(from, '+', 1, rb_funcall(result, '*', 1, step)), cmp, 1, to))) {
2636 result = rb_funcall(result, '+', 1, INT2FIX(1));
2637 }
2638 return result;
2639 }
2640}
2641
2642static int
2643num_step_negative_p(VALUE num)
2644{
2645 const ID mid = '<';
2646 VALUE zero = INT2FIX(0);
2647 VALUE r;
2648
2649 if (FIXNUM_P(num)) {
2650 if (method_basic_p(rb_cInteger))
2651 return (SIGNED_VALUE)num < 0;
2652 }
2653 else if (RB_TYPE_P(num, T_BIGNUM)) {
2654 if (method_basic_p(rb_cInteger))
2655 return BIGNUM_NEGATIVE_P(num);
2656 }
2657
2658 r = rb_check_funcall(num, '>', 1, &zero);
2659 if (r == Qundef) {
2660 coerce_failed(num, INT2FIX(0));
2661 }
2662 return !RTEST(r);
2663}
2664
2665static int
2666num_step_extract_args(int argc, const VALUE *argv, VALUE *to, VALUE *step, VALUE *by)
2667{
2668 VALUE hash;
2669
2670 argc = rb_scan_args(argc, argv, "02:", to, step, &hash);
2671 if (!NIL_P(hash)) {
2672 ID keys[2];
2673 VALUE values[2];
2674 keys[0] = id_to;
2675 keys[1] = id_by;
2676 rb_get_kwargs(hash, keys, 0, 2, values);
2677 if (values[0] != Qundef) {
2678 if (argc > 0) rb_raise(rb_eArgError, "to is given twice");
2679 *to = values[0];
2680 }
2681 if (values[1] != Qundef) {
2682 if (argc > 1) rb_raise(rb_eArgError, "step is given twice");
2683 *by = values[1];
2684 }
2685 }
2686
2687 return argc;
2688}
2689
2690static int
2691num_step_check_fix_args(int argc, VALUE *to, VALUE *step, VALUE by, int fix_nil, int allow_zero_step)
2692{
2693 int desc;
2694 if (by != Qundef) {
2695 *step = by;
2696 }
2697 else {
2698 /* compatibility */
2699 if (argc > 1 && NIL_P(*step)) {
2700 rb_raise(rb_eTypeError, "step must be numeric");
2701 }
2702 }
2703 if (!allow_zero_step && rb_equal(*step, INT2FIX(0))) {
2704 rb_raise(rb_eArgError, "step can't be 0");
2705 }
2706 if (NIL_P(*step)) {
2707 *step = INT2FIX(1);
2708 }
2709 desc = num_step_negative_p(*step);
2710 if (fix_nil && NIL_P(*to)) {
2711 *to = desc ? DBL2NUM(-HUGE_VAL) : DBL2NUM(HUGE_VAL);
2712 }
2713 return desc;
2714}
2715
2716static int
2717num_step_scan_args(int argc, const VALUE *argv, VALUE *to, VALUE *step, int fix_nil, int allow_zero_step)
2718{
2719 VALUE by = Qundef;
2720 argc = num_step_extract_args(argc, argv, to, step, &by);
2721 return num_step_check_fix_args(argc, to, step, by, fix_nil, allow_zero_step);
2722}
2723
2724static VALUE
2725num_step_size(VALUE from, VALUE args, VALUE eobj)
2726{
2727 VALUE to, step;
2728 int argc = args ? RARRAY_LENINT(args) : 0;
2729 const VALUE *argv = args ? RARRAY_CONST_PTR(args) : 0;
2730
2731 num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
2732
2733 return ruby_num_interval_step_size(from, to, step, FALSE);
2734}
2735
2736/*
2737 * call-seq:
2738 * num.step(by: step, to: limit) {|i| block } -> self
2739 * num.step(by: step, to: limit) -> an_enumerator
2740 * num.step(by: step, to: limit) -> an_arithmetic_sequence
2741 * num.step(limit=nil, step=1) {|i| block } -> self
2742 * num.step(limit=nil, step=1) -> an_enumerator
2743 * num.step(limit=nil, step=1) -> an_arithmetic_sequence
2744 *
2745 * Invokes the given block with the sequence of numbers starting at +num+,
2746 * incremented by +step+ (defaulted to +1+) on each call.
2747 *
2748 * The loop finishes when the value to be passed to the block is greater than
2749 * +limit+ (if +step+ is positive) or less than +limit+ (if +step+ is
2750 * negative), where +limit+ is defaulted to infinity.
2751 *
2752 * In the recommended keyword argument style, either or both of
2753 * +step+ and +limit+ (default infinity) can be omitted. In the
2754 * fixed position argument style, zero as a step
2755 * (i.e. <code>num.step(limit, 0)</code>) is not allowed for historical
2756 * compatibility reasons.
2757 *
2758 * If all the arguments are integers, the loop operates using an integer
2759 * counter.
2760 *
2761 * If any of the arguments are floating point numbers, all are converted
2762 * to floats, and the loop is executed
2763 * <i>floor(n + n*Float::EPSILON) + 1</i> times,
2764 * where <i>n = (limit - num)/step</i>.
2765 *
2766 * Otherwise, the loop starts at +num+, uses either the
2767 * less-than (<code><</code>) or greater-than (<code>></code>) operator
2768 * to compare the counter against +limit+,
2769 * and increments itself using the <code>+</code> operator.
2770 *
2771 * If no block is given, an Enumerator is returned instead.
2772 * Especially, the enumerator is an Enumerator::ArithmeticSequence
2773 * if both +limit+ and +step+ are kind of Numeric or <code>nil</code>.
2774 *
2775 * For example:
2776 *
2777 * p 1.step.take(4)
2778 * p 10.step(by: -1).take(4)
2779 * 3.step(to: 5) {|i| print i, " " }
2780 * 1.step(10, 2) {|i| print i, " " }
2781 * Math::E.step(to: Math::PI, by: 0.2) {|f| print f, " " }
2782 *
2783 * Will produce:
2784 *
2785 * [1, 2, 3, 4]
2786 * [10, 9, 8, 7]
2787 * 3 4 5
2788 * 1 3 5 7 9
2789 * 2.718281828459045 2.9182818284590453 3.118281828459045
2790 */
2791
2792static VALUE
2793num_step(int argc, VALUE *argv, VALUE from)
2794{
2795 VALUE to, step;
2796 int desc, inf;
2797
2798 if (!rb_block_given_p()) {
2799 VALUE by = Qundef;
2800
2801 num_step_extract_args(argc, argv, &to, &step, &by);
2802 if (by != Qundef) {
2803 step = by;
2804 }
2805 if (NIL_P(step)) {
2806 step = INT2FIX(1);
2807 }
2808 else if (rb_equal(step, INT2FIX(0))) {
2809 rb_raise(rb_eArgError, "step can't be 0");
2810 }
2811 if ((NIL_P(to) || rb_obj_is_kind_of(to, rb_cNumeric)) &&
2812 rb_obj_is_kind_of(step, rb_cNumeric)) {
2813 return rb_arith_seq_new(from, ID2SYM(rb_frame_this_func()), argc, argv,
2814 num_step_size, from, to, step, FALSE);
2815 }
2816
2817 return SIZED_ENUMERATOR(from, 2, ((VALUE [2]){to, step}), num_step_size);
2818 }
2819
2820 desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
2821 if (rb_equal(step, INT2FIX(0))) {
2822 inf = 1;
2823 }
2824 else if (RB_TYPE_P(to, T_FLOAT)) {
2825 double f = RFLOAT_VALUE(to);
2826 inf = isinf(f) && (signbit(f) ? desc : !desc);
2827 }
2828 else inf = 0;
2829
2830 if (FIXNUM_P(from) && (inf || FIXNUM_P(to)) && FIXNUM_P(step)) {
2831 long i = FIX2LONG(from);
2832 long diff = FIX2LONG(step);
2833
2834 if (inf) {
2835 for (;; i += diff)
2836 rb_yield(LONG2FIX(i));
2837 }
2838 else {
2839 long end = FIX2LONG(to);
2840
2841 if (desc) {
2842 for (; i >= end; i += diff)
2843 rb_yield(LONG2FIX(i));
2844 }
2845 else {
2846 for (; i <= end; i += diff)
2847 rb_yield(LONG2FIX(i));
2848 }
2849 }
2850 }
2851 else if (!ruby_float_step(from, to, step, FALSE, FALSE)) {
2852 VALUE i = from;
2853
2854 if (inf) {
2855 for (;; i = rb_funcall(i, '+', 1, step))
2856 rb_yield(i);
2857 }
2858 else {
2859 ID cmp = desc ? '<' : '>';
2860
2861 for (; !RTEST(rb_funcall(i, cmp, 1, to)); i = rb_funcall(i, '+', 1, step))
2862 rb_yield(i);
2863 }
2864 }
2865 return from;
2866}
2867
2868static char *
2869out_of_range_float(char (*pbuf)[24], VALUE val)
2870{
2871 char *const buf = *pbuf;
2872 char *s;
2873
2874 snprintf(buf, sizeof(*pbuf), "%-.10g", RFLOAT_VALUE(val));
2875 if ((s = strchr(buf, ' ')) != 0) *s = '\0';
2876 return buf;
2877}
2878
2879#define FLOAT_OUT_OF_RANGE(val, type) do { \
2880 char buf[24]; \
2881 rb_raise(rb_eRangeError, "float %s out of range of "type, \
2882 out_of_range_float(&buf, (val))); \
2883} while (0)
2884
2885#define LONG_MIN_MINUS_ONE ((double)LONG_MIN-1)
2886#define LONG_MAX_PLUS_ONE (2*(double)(LONG_MAX/2+1))
2887#define ULONG_MAX_PLUS_ONE (2*(double)(ULONG_MAX/2+1))
2888#define LONG_MIN_MINUS_ONE_IS_LESS_THAN(n) \
2889 (LONG_MIN_MINUS_ONE == (double)LONG_MIN ? \
2890 LONG_MIN <= (n): \
2891 LONG_MIN_MINUS_ONE < (n))
2892
2893long
2894 rb_num2long(VALUE val)
2895{
2896 again:
2897 if (NIL_P(val)) {
2898 rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
2899 }
2900
2901 if (FIXNUM_P(val)) return FIX2LONG(val);
2902
2903 else if (RB_TYPE_P(val, T_FLOAT)) {
2904 if (RFLOAT_VALUE(val) < LONG_MAX_PLUS_ONE
2905 && LONG_MIN_MINUS_ONE_IS_LESS_THAN(RFLOAT_VALUE(val))) {
2906 return (long)RFLOAT_VALUE(val);
2907 }
2908 else {
2909 FLOAT_OUT_OF_RANGE(val, "integer");
2910 }
2911 }
2912 else if (RB_TYPE_P(val, T_BIGNUM)) {
2913 return rb_big2long(val);
2914 }
2915 else {
2916 val = rb_to_int(val);
2917 goto again;
2918 }
2919}
2920
2921static unsigned long
2922rb_num2ulong_internal(VALUE val, int *wrap_p)
2923{
2924 again:
2925 if (NIL_P(val)) {
2926 rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
2927 }
2928
2929 if (FIXNUM_P(val)) {
2930 long l = FIX2LONG(val); /* this is FIX2LONG, intended */
2931 if (wrap_p)
2932 *wrap_p = l < 0;
2933 return (unsigned long)l;
2934 }
2935 else if (RB_TYPE_P(val, T_FLOAT)) {
2936 double d = RFLOAT_VALUE(val);
2937 if (d < ULONG_MAX_PLUS_ONE && LONG_MIN_MINUS_ONE_IS_LESS_THAN(d)) {
2938 if (wrap_p)
2939 *wrap_p = d <= -1.0; /* NUM2ULONG(v) uses v.to_int conceptually. */
2940 if (0 <= d)
2941 return (unsigned long)d;
2942 return (unsigned long)(long)d;
2943 }
2944 else {
2945 FLOAT_OUT_OF_RANGE(val, "integer");
2946 }
2947 }
2948 else if (RB_TYPE_P(val, T_BIGNUM)) {
2949 {
2950 unsigned long ul = rb_big2ulong(val);
2951 if (wrap_p)
2952 *wrap_p = BIGNUM_NEGATIVE_P(val);
2953 return ul;
2954 }
2955 }
2956 else {
2957 val = rb_to_int(val);
2958 goto again;
2959 }
2960}
2961
2962unsigned long
2963 rb_num2ulong(VALUE val)
2964{
2965 return rb_num2ulong_internal(val, NULL);
2966}
2967
2968void
2969 rb_out_of_int(SIGNED_VALUE num)
2970{
2971 rb_raise(rb_eRangeError, "integer %"PRIdVALUE " too %s to convert to `int'",
2972 num, num < 0 ? "small" : "big");
2973}
2974
2975#if SIZEOF_INT < SIZEOF_LONG
2976static void
2977check_int(long num)
2978{
2979 if ((long)(int)num != num) {
2980 rb_out_of_int(num);
2981 }
2982}
2983
2984static void
2985check_uint(unsigned long num, int sign)
2986{
2987 if (sign) {
2988 /* minus */
2989 if (num < (unsigned long)INT_MIN)
2990 rb_raise(rb_eRangeError, "integer %ld too small to convert to `unsigned int'", (long)num);
2991 }
2992 else {
2993 /* plus */
2994 if (UINT_MAX < num)
2995 rb_raise(rb_eRangeError, "integer %lu too big to convert to `unsigned int'", num);
2996 }
2997}
2998
2999long
3000 rb_num2int(VALUE val)
3001{
3002 long num = rb_num2long(val);
3003
3004 check_int(num);
3005 return num;
3006}
3007
3008long
3009 rb_fix2int(VALUE val)
3010{
3011 long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val);
3012
3013 check_int(num);
3014 return num;
3015}
3016
3017unsigned long
3018 rb_num2uint(VALUE val)
3019{
3020 int wrap;
3021 unsigned long num = rb_num2ulong_internal(val, &wrap);
3022
3023 check_uint(num, wrap);
3024 return num;
3025}
3026
3027unsigned long
3028 rb_fix2uint(VALUE val)
3029{
3030 unsigned long num;
3031
3032 if (!FIXNUM_P(val)) {
3033 return rb_num2uint(val);
3034 }
3035 num = FIX2ULONG(val);
3036
3037 check_uint(num, rb_num_negative_int_p(val));
3038 return num;
3039}
3040#else
3041long
3042 rb_num2int(VALUE val)
3043{
3044 return rb_num2long(val);
3045}
3046
3047long
3048 rb_fix2int(VALUE val)
3049{
3050 return FIX2INT(val);
3051}
3052
3053unsigned long
3054 rb_num2uint(VALUE val)
3055{
3056 return rb_num2ulong(val);
3057}
3058
3059unsigned long
3060 rb_fix2uint(VALUE val)
3061{
3062 return RB_FIX2ULONG(val);
3063}
3064#endif
3065
3066 NORETURN(static void rb_out_of_short(SIGNED_VALUE num));
3067static void
3068rb_out_of_short(SIGNED_VALUE num)
3069{
3070 rb_raise(rb_eRangeError, "integer %"PRIdVALUE " too %s to convert to `short'",
3071 num, num < 0 ? "small" : "big");
3072}
3073
3074static void
3075check_short(long num)
3076{
3077 if ((long)(short)num != num) {
3078 rb_out_of_short(num);
3079 }
3080}
3081
3082static void
3083check_ushort(unsigned long num, int sign)
3084{
3085 if (sign) {
3086 /* minus */
3087 if (num < (unsigned long)SHRT_MIN)
3088 rb_raise(rb_eRangeError, "integer %ld too small to convert to `unsigned short'", (long)num);
3089 }
3090 else {
3091 /* plus */
3092 if (USHRT_MAX < num)
3093 rb_raise(rb_eRangeError, "integer %lu too big to convert to `unsigned short'", num);
3094 }
3095}
3096
3097short
3098 rb_num2short(VALUE val)
3099{
3100 long num = rb_num2long(val);
3101
3102 check_short(num);
3103 return num;
3104}
3105
3106short
3107 rb_fix2short(VALUE val)
3108{
3109 long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val);
3110
3111 check_short(num);
3112 return num;
3113}
3114
3115unsigned short
3116 rb_num2ushort(VALUE val)
3117{
3118 int wrap;
3119 unsigned long num = rb_num2ulong_internal(val, &wrap);
3120
3121 check_ushort(num, wrap);
3122 return num;
3123}
3124
3125unsigned short
3126 rb_fix2ushort(VALUE val)
3127{
3128 unsigned long num;
3129
3130 if (!FIXNUM_P(val)) {
3131 return rb_num2ushort(val);
3132 }
3133 num = FIX2ULONG(val);
3134
3135 check_ushort(num, rb_num_negative_int_p(val));
3136 return num;
3137}
3138
3139 VALUE
3140 rb_num2fix(VALUE val)
3141{
3142 long v;
3143
3144 if (FIXNUM_P(val)) return val;
3145
3146 v = rb_num2long(val);
3147 if (!FIXABLE(v))
3148 rb_raise(rb_eRangeError, "integer %ld out of range of fixnum", v);
3149 return LONG2FIX(v);
3150}
3151
3152#if HAVE_LONG_LONG
3153
3154#define LLONG_MIN_MINUS_ONE ((double)LLONG_MIN-1)
3155#define LLONG_MAX_PLUS_ONE (2*(double)(LLONG_MAX/2+1))
3156#define ULLONG_MAX_PLUS_ONE (2*(double)(ULLONG_MAX/2+1))
3157#ifndef ULLONG_MAX
3158#define ULLONG_MAX ((unsigned LONG_LONG)LLONG_MAX*2+1)
3159#endif
3160#define LLONG_MIN_MINUS_ONE_IS_LESS_THAN(n) \
3161 (LLONG_MIN_MINUS_ONE == (double)LLONG_MIN ? \
3162 LLONG_MIN <= (n): \
3163 LLONG_MIN_MINUS_ONE < (n))
3164
3165LONG_LONG
3166 rb_num2ll(VALUE val)
3167{
3168 if (NIL_P(val)) {
3169 rb_raise(rb_eTypeError, "no implicit conversion from nil");
3170 }
3171
3172 if (FIXNUM_P(val)) return (LONG_LONG)FIX2LONG(val);
3173
3174 else if (RB_TYPE_P(val, T_FLOAT)) {
3175 double d = RFLOAT_VALUE(val);
3176 if (d < LLONG_MAX_PLUS_ONE && (LLONG_MIN_MINUS_ONE_IS_LESS_THAN(d))) {
3177 return (LONG_LONG)d;
3178 }
3179 else {
3180 FLOAT_OUT_OF_RANGE(val, "long long");
3181 }
3182 }
3183 else if (RB_TYPE_P(val, T_BIGNUM)) {
3184 return rb_big2ll(val);
3185 }
3186 else if (RB_TYPE_P(val, T_STRING)) {
3187 rb_raise(rb_eTypeError, "no implicit conversion from string");
3188 }
3189 else if (RB_TYPE_P(val, T_TRUE) || RB_TYPE_P(val, T_FALSE)) {
3190 rb_raise(rb_eTypeError, "no implicit conversion from boolean");
3191 }
3192
3193 val = rb_to_int(val);
3194 return NUM2LL(val);
3195}
3196
3197unsigned LONG_LONG
3198 rb_num2ull(VALUE val)
3199{
3200 if (RB_TYPE_P(val, T_NIL)) {
3201 rb_raise(rb_eTypeError, "no implicit conversion from nil");
3202 }
3203 else if (RB_TYPE_P(val, T_FIXNUM)) {
3204 return (LONG_LONG)FIX2LONG(val); /* this is FIX2LONG, intended */
3205 }
3206 else if (RB_TYPE_P(val, T_FLOAT)) {
3207 double d = RFLOAT_VALUE(val);
3208 if (d < ULLONG_MAX_PLUS_ONE && LLONG_MIN_MINUS_ONE_IS_LESS_THAN(d)) {
3209 if (0 <= d)
3210 return (unsigned LONG_LONG)d;
3211 return (unsigned LONG_LONG)(LONG_LONG)d;
3212 }
3213 else {
3214 FLOAT_OUT_OF_RANGE(val, "unsigned long long");
3215 }
3216 }
3217 else if (RB_TYPE_P(val, T_BIGNUM)) {
3218 return rb_big2ull(val);
3219 }
3220 else if (RB_TYPE_P(val, T_STRING)) {
3221 rb_raise(rb_eTypeError, "no implicit conversion from string");
3222 }
3223 else if (RB_TYPE_P(val, T_TRUE) || RB_TYPE_P(val, T_FALSE)) {
3224 rb_raise(rb_eTypeError, "no implicit conversion from boolean");
3225 }
3226
3227 val = rb_to_int(val);
3228 return NUM2ULL(val);
3229}
3230
3231#endif /* HAVE_LONG_LONG */
3232
3233/********************************************************************
3234 *
3235 * Document-class: Integer
3236 *
3237 * Holds Integer values. You cannot add a singleton method to an
3238 * Integer object, any attempt to do so will raise a TypeError.
3239 *
3240 */
3241
3242 VALUE
3243 rb_int_odd_p(VALUE num)
3244{
3245 if (FIXNUM_P(num)) {
3246 if (num & 2) {
3247 return Qtrue;
3248 }
3249 return Qfalse;
3250 }
3251 else {
3252 assert(RB_TYPE_P(num, T_BIGNUM));
3253 return rb_big_odd_p(num);
3254 }
3255}
3256
3257static VALUE
3258int_even_p(VALUE num)
3259{
3260 if (FIXNUM_P(num)) {
3261 if ((num & 2) == 0) {
3262 return Qtrue;
3263 }
3264 return Qfalse;
3265 }
3266 else {
3267 assert(RB_TYPE_P(num, T_BIGNUM));
3268 return rb_big_even_p(num);
3269 }
3270}
3271
3272 VALUE
3273 rb_int_even_p(VALUE num)
3274{
3275 return int_even_p(num);
3276}
3277
3278/*
3279 * call-seq:
3280 * int.allbits?(mask) -> true or false
3281 *
3282 * Returns +true+ if all bits of <code>+int+ & +mask+</code> are 1.
3283 */
3284
3285static VALUE
3286int_allbits_p(VALUE num, VALUE mask)
3287{
3288 mask = rb_to_int(mask);
3289 return rb_int_equal(rb_int_and(num, mask), mask);
3290}
3291
3292/*
3293 * call-seq:
3294 * int.anybits?(mask) -> true or false
3295 *
3296 * Returns +true+ if any bits of <code>+int+ & +mask+</code> are 1.
3297 */
3298
3299static VALUE
3300int_anybits_p(VALUE num, VALUE mask)
3301{
3302 mask = rb_to_int(mask);
3303 return int_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue;
3304}
3305
3306/*
3307 * call-seq:
3308 * int.nobits?(mask) -> true or false
3309 *
3310 * Returns +true+ if no bits of <code>+int+ & +mask+</code> are 1.
3311 */
3312
3313static VALUE
3314int_nobits_p(VALUE num, VALUE mask)
3315{
3316 mask = rb_to_int(mask);
3317 return int_zero_p(rb_int_and(num, mask));
3318}
3319
3320/*
3321 * Document-method: Integer#succ
3322 * Document-method: Integer#next
3323 * call-seq:
3324 * int.next -> integer
3325 * int.succ -> integer
3326 *
3327 * Returns the successor of +int+,
3328 * i.e. the Integer equal to <code>int+1</code>.
3329 *
3330 * 1.next #=> 2
3331 * (-1).next #=> 0
3332 * 1.succ #=> 2
3333 * (-1).succ #=> 0
3334 */
3335
3336 VALUE
3337 rb_int_succ(VALUE num)
3338{
3339 if (FIXNUM_P(num)) {
3340 long i = FIX2LONG(num) + 1;
3341 return LONG2NUM(i);
3342 }
3343 if (RB_TYPE_P(num, T_BIGNUM)) {
3344 return rb_big_plus(num, INT2FIX(1));
3345 }
3346 return num_funcall1(num, '+', INT2FIX(1));
3347}
3348
3349#define int_succ rb_int_succ
3350
3351/*
3352 * call-seq:
3353 * int.pred -> integer
3354 *
3355 * Returns the predecessor of +int+,
3356 * i.e. the Integer equal to <code>int-1</code>.
3357 *
3358 * 1.pred #=> 0
3359 * (-1).pred #=> -2
3360 */
3361
3362static VALUE
3363rb_int_pred(VALUE num)
3364{
3365 if (FIXNUM_P(num)) {
3366 long i = FIX2LONG(num) - 1;
3367 return LONG2NUM(i);
3368 }
3369 if (RB_TYPE_P(num, T_BIGNUM)) {
3370 return rb_big_minus(num, INT2FIX(1));
3371 }
3372 return num_funcall1(num, '-', INT2FIX(1));
3373}
3374
3375#define int_pred rb_int_pred
3376
3377/*
3378 * Document-method: Integer#chr
3379 * call-seq:
3380 * int.chr([encoding]) -> string
3381 *
3382 * Returns a string containing the character represented by the +int+'s value
3383 * according to +encoding+.
3384 *
3385 * 65.chr #=> "A"
3386 * 230.chr #=> "\xE6"
3387 * 255.chr(Encoding::UTF_8) #=> "\u00FF"
3388 */
3389
3390 VALUE
3391 rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
3392{
3393 int n;
3394 VALUE str;
3395 switch (n = rb_enc_codelen(code, enc)) {
3396 case ONIGERR_INVALID_CODE_POINT_VALUE:
3397 rb_raise(rb_eRangeError, "invalid codepoint 0x%X in %s", code, rb_enc_name(enc));
3398 break;
3399 case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE:
3400 case 0:
3401 rb_raise(rb_eRangeError, "%u out of char range", code);
3402 break;
3403 }
3404 str = rb_enc_str_new(0, n, enc);
3405 rb_enc_mbcput(code, RSTRING_PTR(str), enc);
3406 if (rb_enc_precise_mbclen(RSTRING_PTR(str), RSTRING_END(str), enc) != n) {
3407 rb_raise(rb_eRangeError, "invalid codepoint 0x%X in %s", code, rb_enc_name(enc));
3408 }
3409 return str;
3410}
3411
3412static VALUE
3413int_chr(int argc, VALUE *argv, VALUE num)
3414{
3415 char c;
3416 unsigned int i;
3417 rb_encoding *enc;
3418
3419 if (rb_num_to_uint(num, &i) == 0) {
3420 }
3421 else if (FIXNUM_P(num)) {
3422 rb_raise(rb_eRangeError, "%ld out of char range", FIX2LONG(num));
3423 }
3424 else {
3425 rb_raise(rb_eRangeError, "bignum out of char range");
3426 }
3427
3428 switch (argc) {
3429 case 0:
3430 if (0xff < i) {
3431 enc = rb_default_internal_encoding();
3432 if (!enc) {
3433 rb_raise(rb_eRangeError, "%u out of char range", i);
3434 }
3435 goto decode;
3436 }
3437 c = (char)i;
3438 if (i < 0x80) {
3439 return rb_usascii_str_new(&c, 1);
3440 }
3441 else {
3442 return rb_str_new(&c, 1);
3443 }
3444 case 1:
3445 break;
3446 default:
3447 rb_error_arity(argc, 0, 1);
3448 }
3449 enc = rb_to_encoding(argv[0]);
3450 if (!enc) enc = rb_ascii8bit_encoding();
3451 decode:
3452 return rb_enc_uint_chr(i, enc);
3453}
3454
3455/*
3456 * Fixnum
3457 */
3458
3459static VALUE
3460fix_uminus(VALUE num)
3461{
3462 return LONG2NUM(-FIX2LONG(num));
3463}
3464
3465 VALUE
3466 rb_int_uminus(VALUE num)
3467{
3468 if (FIXNUM_P(num)) {
3469 return fix_uminus(num);
3470 }
3471 else {
3472 assert(RB_TYPE_P(num, T_BIGNUM));
3473 return rb_big_uminus(num);
3474 }
3475}
3476
3477/*
3478 * Document-method: Integer#to_s
3479 * call-seq:
3480 * int.to_s(base=10) -> string
3481 *
3482 * Returns a string containing the place-value representation of +int+
3483 * with radix +base+ (between 2 and 36).
3484 *
3485 * 12345.to_s #=> "12345"
3486 * 12345.to_s(2) #=> "11000000111001"
3487 * 12345.to_s(8) #=> "30071"
3488 * 12345.to_s(10) #=> "12345"
3489 * 12345.to_s(16) #=> "3039"
3490 * 12345.to_s(36) #=> "9ix"
3491 * 78546939656932.to_s(36) #=> "rubyrules"
3492 */
3493
3494 VALUE
3495 rb_fix2str(VALUE x, int base)
3496{
3497 char buf[SIZEOF_VALUE*CHAR_BIT + 1], *const e = buf + sizeof buf, *b = e;
3498 long val = FIX2LONG(x);
3499 unsigned long u;
3500 int neg = 0;
3501
3502 if (base < 2 || 36 < base) {
3503 rb_raise(rb_eArgError, "invalid radix %d", base);
3504 }
3505#if SIZEOF_LONG < SIZEOF_VOIDP
3506# if SIZEOF_VOIDP == SIZEOF_LONG_LONG
3507 if ((val >= 0 && (x & 0xFFFFFFFF00000000ull)) ||
3508 (val < 0 && (x & 0xFFFFFFFF00000000ull) != 0xFFFFFFFF00000000ull)) {
3509 rb_bug("Unnormalized Fixnum value %p", (void *)x);
3510 }
3511# else
3512 /* should do something like above code, but currently ruby does not know */
3513 /* such platforms */
3514# endif
3515#endif
3516 if (val == 0) {
3517 return rb_usascii_str_new2("0");
3518 }
3519 if (val < 0) {
3520 u = 1 + (unsigned long)(-(val + 1)); /* u = -val avoiding overflow */
3521 neg = 1;
3522 }
3523 else {
3524 u = val;
3525 }
3526 do {
3527 *--b = ruby_digitmap[(int)(u % base)];
3528 } while (u /= base);
3529 if (neg) {
3530 *--b = '-';
3531 }
3532
3533 return rb_usascii_str_new(b, e - b);
3534}
3535
3536static VALUE
3537int_to_s(int argc, VALUE *argv, VALUE x)
3538{
3539 int base;
3540
3541 if (rb_check_arity(argc, 0, 1))
3542 base = NUM2INT(argv[0]);
3543 else
3544 base = 10;
3545 return rb_int2str(x, base);
3546}
3547
3548 VALUE
3549 rb_int2str(VALUE x, int base)
3550{
3551 if (FIXNUM_P(x)) {
3552 return rb_fix2str(x, base);
3553 }
3554 else if (RB_TYPE_P(x, T_BIGNUM)) {
3555 return rb_big2str(x, base);
3556 }
3557
3558 return rb_any_to_s(x);
3559}
3560
3561/*
3562 * Document-method: Integer#+
3563 * call-seq:
3564 * int + numeric -> numeric_result
3565 *
3566 * Performs addition: the class of the resulting object depends on
3567 * the class of +numeric+.
3568 */
3569
3570static VALUE
3571fix_plus(VALUE x, VALUE y)
3572{
3573 if (FIXNUM_P(y)) {
3574 return rb_fix_plus_fix(x, y);
3575 }
3576 else if (RB_TYPE_P(y, T_BIGNUM)) {
3577 return rb_big_plus(y, x);
3578 }
3579 else if (RB_TYPE_P(y, T_FLOAT)) {
3580 return DBL2NUM((double)FIX2LONG(x) + RFLOAT_VALUE(y));
3581 }
3582 else if (RB_TYPE_P(y, T_COMPLEX)) {
3583 return rb_complex_plus(y, x);
3584 }
3585 else {
3586 return rb_num_coerce_bin(x, y, '+');
3587 }
3588}
3589
3590 VALUE
3591 rb_fix_plus(VALUE x, VALUE y)
3592{
3593 return fix_plus(x, y);
3594}
3595
3596 VALUE
3597 rb_int_plus(VALUE x, VALUE y)
3598{
3599 if (FIXNUM_P(x)) {
3600 return fix_plus(x, y);
3601 }
3602 else if (RB_TYPE_P(x, T_BIGNUM)) {
3603 return rb_big_plus(x, y);
3604 }
3605 return rb_num_coerce_bin(x, y, '+');
3606}
3607
3608/*
3609 * Document-method: Integer#-
3610 * call-seq:
3611 * int - numeric -> numeric_result
3612 *
3613 * Performs subtraction: the class of the resulting object depends on
3614 * the class of +numeric+.
3615 */
3616
3617static VALUE
3618fix_minus(VALUE x, VALUE y)
3619{
3620 if (FIXNUM_P(y)) {
3621 return rb_fix_minus_fix(x, y);
3622 }
3623 else if (RB_TYPE_P(y, T_BIGNUM)) {
3624 x = rb_int2big(FIX2LONG(x));
3625 return rb_big_minus(x, y);
3626 }
3627 else if (RB_TYPE_P(y, T_FLOAT)) {
3628 return DBL2NUM((double)FIX2LONG(x) - RFLOAT_VALUE(y));
3629 }
3630 else {
3631 return rb_num_coerce_bin(x, y, '-');
3632 }
3633}
3634
3635 VALUE
3636 rb_int_minus(VALUE x, VALUE y)
3637{
3638 if (FIXNUM_P(x)) {
3639 return fix_minus(x, y);
3640 }
3641 else if (RB_TYPE_P(x, T_BIGNUM)) {
3642 return rb_big_minus(x, y);
3643 }
3644 return rb_num_coerce_bin(x, y, '-');
3645}
3646
3647
3648#define SQRT_LONG_MAX HALF_LONG_MSB
3649/*tests if N*N would overflow*/
3650#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
3651
3652/*
3653 * Document-method: Integer#*
3654 * call-seq:
3655 * int * numeric -> numeric_result
3656 *
3657 * Performs multiplication: the class of the resulting object depends on
3658 * the class of +numeric+.
3659 */
3660
3661static VALUE
3662fix_mul(VALUE x, VALUE y)
3663{
3664 if (FIXNUM_P(y)) {
3665 return rb_fix_mul_fix(x, y);
3666 }
3667 else if (RB_TYPE_P(y, T_BIGNUM)) {
3668 switch (x) {
3669 case INT2FIX(0): return x;
3670 case INT2FIX(1): return y;
3671 }
3672 return rb_big_mul(y, x);
3673 }
3674 else if (RB_TYPE_P(y, T_FLOAT)) {
3675 return DBL2NUM((double)FIX2LONG(x) * RFLOAT_VALUE(y));
3676 }
3677 else if (RB_TYPE_P(y, T_COMPLEX)) {
3678 return rb_complex_mul(y, x);
3679 }
3680 else {
3681 return rb_num_coerce_bin(x, y, '*');
3682 }
3683}
3684
3685 VALUE
3686 rb_int_mul(VALUE x, VALUE y)
3687{
3688 if (FIXNUM_P(x)) {
3689 return fix_mul(x, y);
3690 }
3691 else if (RB_TYPE_P(x, T_BIGNUM)) {
3692 return rb_big_mul(x, y);
3693 }
3694 return rb_num_coerce_bin(x, y, '*');
3695}
3696
3697static double
3698fix_fdiv_double(VALUE x, VALUE y)
3699{
3700 if (FIXNUM_P(y)) {
3701 return double_div_double(FIX2LONG(x), FIX2LONG(y));
3702 }
3703 else if (RB_TYPE_P(y, T_BIGNUM)) {
3704 return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), y);
3705 }
3706 else if (RB_TYPE_P(y, T_FLOAT)) {
3707 return double_div_double(FIX2LONG(x), RFLOAT_VALUE(y));
3708 }
3709 else {
3710 return NUM2DBL(rb_num_coerce_bin(x, y, idFdiv));
3711 }
3712}
3713
3714double
3715 rb_int_fdiv_double(VALUE x, VALUE y)
3716{
3717 if (RB_INTEGER_TYPE_P(y) && !FIXNUM_ZERO_P(y)) {
3718 VALUE gcd = rb_gcd(x, y);
3719 if (!FIXNUM_ZERO_P(gcd)) {
3720 x = rb_int_idiv(x, gcd);
3721 y = rb_int_idiv(y, gcd);
3722 }
3723 }
3724 if (FIXNUM_P(x)) {
3725 return fix_fdiv_double(x, y);
3726 }
3727 else if (RB_TYPE_P(x, T_BIGNUM)) {
3728 return rb_big_fdiv_double(x, y);
3729 }
3730 else {
3731 return nan("");
3732 }
3733}
3734
3735/*
3736 * Document-method: Integer#fdiv
3737 * call-seq:
3738 * int.fdiv(numeric) -> float
3739 *
3740 * Returns the floating point result of dividing +int+ by +numeric+.
3741 *
3742 * 654321.fdiv(13731) #=> 47.652829364212366
3743 * 654321.fdiv(13731.24) #=> 47.65199646936475
3744 * -654321.fdiv(13731) #=> -47.652829364212366
3745 */
3746
3747 VALUE
3748rb_int_fdiv(VALUE x, VALUE y)
3749{
3750 if (RB_INTEGER_TYPE_P(x)) {
3751 return DBL2NUM(rb_int_fdiv_double(x, y));
3752 }
3753 return Qnil;
3754}
3755
3756/*
3757 * Document-method: Integer#/
3758 * call-seq:
3759 * int / numeric -> numeric_result
3760 *
3761 * Performs division: the class of the resulting object depends on
3762 * the class of +numeric+.
3763 */
3764
3765static VALUE
3766fix_divide(VALUE x, VALUE y, ID op)
3767{
3768 if (FIXNUM_P(y)) {
3769 if (FIXNUM_ZERO_P(y)) rb_num_zerodiv();
3770 return rb_fix_div_fix(x, y);
3771 }
3772 else if (RB_TYPE_P(y, T_BIGNUM)) {
3773 x = rb_int2big(FIX2LONG(x));
3774 return rb_big_div(x, y);
3775 }
3776 else if (RB_TYPE_P(y, T_FLOAT)) {
3777 if (op == '/') {
3778 double d = FIX2LONG(x);
3779 return rb_flo_div_flo(DBL2NUM(d), y);
3780 }
3781 else {
3782 VALUE v;
3783 if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv();
3784 v = fix_divide(x, y, '/');
3785 return flo_floor(0, 0, v);
3786 }
3787 }
3788 else {
3789 if (RB_TYPE_P(y, T_RATIONAL) &&
3790 op == '/' && FIX2LONG(x) == 1)
3791 return rb_rational_reciprocal(y);
3792 return rb_num_coerce_bin(x, y, op);
3793 }
3794}
3795
3796static VALUE
3797fix_div(VALUE x, VALUE y)
3798{
3799 return fix_divide(x, y, '/');
3800}
3801
3802 VALUE
3803 rb_int_div(VALUE x, VALUE y)
3804{
3805 if (FIXNUM_P(x)) {
3806 return fix_div(x, y);
3807 }
3808 else if (RB_TYPE_P(x, T_BIGNUM)) {
3809 return rb_big_div(x, y);
3810 }
3811 return Qnil;
3812}
3813
3814/*
3815 * Document-method: Integer#div
3816 * call-seq:
3817 * int.div(numeric) -> integer
3818 *
3819 * Performs integer division: returns the integer result of dividing +int+
3820 * by +numeric+.
3821 */
3822
3823static VALUE
3824fix_idiv(VALUE x, VALUE y)
3825{
3826 return fix_divide(x, y, id_div);
3827}
3828
3829 VALUE
3830 rb_int_idiv(VALUE x, VALUE y)
3831{
3832 if (FIXNUM_P(x)) {
3833 return fix_idiv(x, y);
3834 }
3835 else if (RB_TYPE_P(x, T_BIGNUM)) {
3836 return rb_big_idiv(x, y);
3837 }
3838 return num_div(x, y);
3839}
3840
3841/*
3842 * Document-method: Integer#%
3843 * Document-method: Integer#modulo
3844 * call-seq:
3845 * int % other -> real
3846 * int.modulo(other) -> real
3847 *
3848 * Returns +int+ modulo +other+.
3849 *
3850 * See Numeric#divmod for more information.
3851 */
3852
3853static VALUE
3854fix_mod(VALUE x, VALUE y)
3855{
3856 if (FIXNUM_P(y)) {
3857 if (FIXNUM_ZERO_P(y)) rb_num_zerodiv();
3858 return rb_fix_mod_fix(x, y);
3859 }
3860 else if (RB_TYPE_P(y, T_BIGNUM)) {
3861 x = rb_int2big(FIX2LONG(x));
3862 return rb_big_modulo(x, y);
3863 }
3864 else if (RB_TYPE_P(y, T_FLOAT)) {
3865 return DBL2NUM(ruby_float_mod((double)FIX2LONG(x), RFLOAT_VALUE(y)));
3866 }
3867 else {
3868 return rb_num_coerce_bin(x, y, '%');
3869 }
3870}
3871
3872 VALUE
3873 rb_int_modulo(VALUE x, VALUE y)
3874{
3875 if (FIXNUM_P(x)) {
3876 return fix_mod(x, y);
3877 }
3878 else if (RB_TYPE_P(x, T_BIGNUM)) {
3879 return rb_big_modulo(x, y);
3880 }
3881 return num_modulo(x, y);
3882}
3883
3884/*
3885 * call-seq:
3886 * int.remainder(numeric) -> real
3887 *
3888 * Returns the remainder after dividing +int+ by +numeric+.
3889 *
3890 * <code>x.remainder(y)</code> means <code>x-y*(x/y).truncate</code>.
3891 *
3892 * 5.remainder(3) #=> 2
3893 * -5.remainder(3) #=> -2
3894 * 5.remainder(-3) #=> 2
3895 * -5.remainder(-3) #=> -2
3896 * 5.remainder(1.5) #=> 0.5
3897 *
3898 * See Numeric#divmod.
3899 */
3900
3901static VALUE
3902int_remainder(VALUE x, VALUE y)
3903{
3904 if (FIXNUM_P(x)) {
3905 return num_remainder(x, y);
3906 }
3907 else if (RB_TYPE_P(x, T_BIGNUM)) {
3908 return rb_big_remainder(x, y);
3909 }
3910 return Qnil;
3911}
3912
3913/*
3914 * Document-method: Integer#divmod
3915 * call-seq:
3916 * int.divmod(numeric) -> array
3917 *
3918 * See Numeric#divmod.
3919 */
3920static VALUE
3921fix_divmod(VALUE x, VALUE y)
3922{
3923 if (FIXNUM_P(y)) {
3924 VALUE div, mod;
3925 if (FIXNUM_ZERO_P(y)) rb_num_zerodiv();
3926 rb_fix_divmod_fix(x, y, &div, &mod);
3927 return rb_assoc_new(div, mod);
3928 }
3929 else if (RB_TYPE_P(y, T_BIGNUM)) {
3930 x = rb_int2big(FIX2LONG(x));
3931 return rb_big_divmod(x, y);
3932 }
3933 else if (RB_TYPE_P(y, T_FLOAT)) {
3934 {
3935 double div, mod;
3936 volatile VALUE a, b;
3937
3938 flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), &div, &mod);
3939 a = dbl2ival(div);
3940 b = DBL2NUM(mod);
3941 return rb_assoc_new(a, b);
3942 }
3943 }
3944 else {
3945 return rb_num_coerce_bin(x, y, id_divmod);
3946 }
3947}
3948
3949 VALUE
3950 rb_int_divmod(VALUE x, VALUE y)
3951{
3952 if (FIXNUM_P(x)) {
3953 return fix_divmod(x, y);
3954 }
3955 else if (RB_TYPE_P(x, T_BIGNUM)) {
3956 return rb_big_divmod(x, y);
3957 }
3958 return Qnil;
3959}
3960
3961/*
3962 * Document-method: Integer#**
3963 * call-seq:
3964 * int ** numeric -> numeric_result
3965 *
3966 * Raises +int+ to the power of +numeric+, which may be negative or
3967 * fractional.
3968 * The result may be an Integer, a Float, a Rational, or a complex number.
3969 *
3970 * 2 ** 3 #=> 8
3971 * 2 ** -1 #=> (1/2)
3972 * 2 ** 0.5 #=> 1.4142135623730951
3973 * (-1) ** 0.5 #=> (0.0+1.0i)
3974 *
3975 * 123456789 ** 2 #=> 15241578750190521
3976 * 123456789 ** 1.2 #=> 5126464716.0993185
3977 * 123456789 ** -2 #=> (1/15241578750190521)
3978 */
3979
3980static VALUE
3981int_pow(long x, unsigned long y)
3982{
3983 int neg = x < 0;
3984 long z = 1;
3985
3986 if (y == 0) return INT2FIX(1);
3987 if (y == 1) return LONG2NUM(x);
3988 if (neg) x = -x;
3989 if (y & 1)
3990 z = x;
3991 else
3992 neg = 0;
3993 y &= ~1;
3994 do {
3995 while (y % 2 == 0) {
3996 if (!FIT_SQRT_LONG(x)) {
3997 goto bignum;
3998 }
3999 x = x * x;
4000 y >>= 1;
4001 }
4002 {
4003 if (MUL_OVERFLOW_FIXNUM_P(x, z)) {
4004 goto bignum;
4005 }
4006 z = x * z;
4007 }
4008 } while (--y);
4009 if (neg) z = -z;
4010 return LONG2NUM(z);
4011
4012 VALUE v;
4013 bignum:
4014 v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
4015 if (RB_FLOAT_TYPE_P(v)) /* infinity due to overflow */
4016 return v;
4017 if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
4018 return v;
4019}
4020
4021 VALUE
4022 rb_int_positive_pow(long x, unsigned long y)
4023{
4024 return int_pow(x, y);
4025}
4026
4027static VALUE
4028fix_pow_inverted(VALUE x, VALUE minusb)
4029{
4030 if (x == INT2FIX(0)) {
4031 rb_num_zerodiv();
4032 UNREACHABLE_RETURN(Qundef);
4033 }
4034 else {
4035 VALUE y = rb_int_pow(x, minusb);
4036
4037 if (RB_FLOAT_TYPE_P(y)) {
4038 double d = pow((double)FIX2LONG(x), RFLOAT_VALUE(y));
4039 return DBL2NUM(1.0 / d);
4040 }
4041 else {
4042 return rb_rational_raw(INT2FIX(1), y);
4043 }
4044 }
4045}
4046
4047static VALUE
4048fix_pow(VALUE x, VALUE y)
4049{
4050 long a = FIX2LONG(x);
4051
4052 if (FIXNUM_P(y)) {
4053 long b = FIX2LONG(y);
4054
4055 if (a == 1) return INT2FIX(1);
4056 if (a == -1) return INT2FIX(b % 2 ? -1 : 1);
4057 if (b < 0) return fix_pow_inverted(x, fix_uminus(y));
4058 if (b == 0) return INT2FIX(1);
4059 if (b == 1) return x;
4060 if (a == 0) return INT2FIX(0);
4061 return int_pow(a, b);
4062 }
4063 else if (RB_TYPE_P(y, T_BIGNUM)) {
4064 if (a == 1) return INT2FIX(1);
4065 if (a == -1) return INT2FIX(int_even_p(y) ? 1 : -1);
4066 if (BIGNUM_NEGATIVE_P(y)) return fix_pow_inverted(x, rb_big_uminus(y));
4067 if (a == 0) return INT2FIX(0);
4068 x = rb_int2big(FIX2LONG(x));
4069 return rb_big_pow(x, y);
4070 }
4071 else if (RB_TYPE_P(y, T_FLOAT)) {
4072 double dy = RFLOAT_VALUE(y);
4073 if (dy == 0.0) return DBL2NUM(1.0);
4074 if (a == 0) {
4075 return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0);
4076 }
4077 if (a == 1) return DBL2NUM(1.0);
4078 if (a < 0 && dy != round(dy))
4079 return rb_dbl_complex_new_polar_pi(pow(-(double)a, dy), dy);
4080 return DBL2NUM(pow((double)a, dy));
4081 }
4082 else {
4083 return rb_num_coerce_bin(x, y, idPow);
4084 }
4085}
4086
4087 VALUE
4088 rb_int_pow(VALUE x, VALUE y)
4089{
4090 if (FIXNUM_P(x)) {
4091 return fix_pow(x, y);
4092 }
4093 else if (RB_TYPE_P(x, T_BIGNUM)) {
4094 return rb_big_pow(x, y);
4095 }
4096 return Qnil;
4097}
4098
4099 VALUE
4100 rb_num_pow(VALUE x, VALUE y)
4101{
4102 VALUE z = rb_int_pow(x, y);
4103 if (!NIL_P(z)) return z;
4104 if (RB_FLOAT_TYPE_P(x)) return rb_float_pow(x, y);
4105 if (SPECIAL_CONST_P(x)) return Qnil;
4106 switch (BUILTIN_TYPE(x)) {
4107 case T_COMPLEX:
4108 return rb_complex_pow(x, y);
4109 case T_RATIONAL:
4110 return rb_rational_pow(x, y);
4111 default:
4112 break;
4113 }
4114 return Qnil;
4115}
4116
4117/*
4118 * Document-method: Integer#==
4119 * Document-method: Integer#===
4120 * call-seq:
4121 * int == other -> true or false
4122 *
4123 * Returns +true+ if +int+ equals +other+ numerically.
4124 * Contrast this with Integer#eql?, which requires +other+ to be an Integer.
4125 *
4126 * 1 == 2 #=> false
4127 * 1 == 1.0 #=> true
4128 */
4129
4130static VALUE
4131fix_equal(VALUE x, VALUE y)
4132{
4133 if (x == y) return Qtrue;
4134 if (FIXNUM_P(y)) return Qfalse;
4135 else if (RB_TYPE_P(y, T_BIGNUM)) {
4136 return rb_big_eq(y, x);
4137 }
4138 else if (RB_TYPE_P(y, T_FLOAT)) {
4139 return rb_integer_float_eq(x, y);
4140 }
4141 else {
4142 return num_equal(x, y);
4143 }
4144}
4145
4146 VALUE
4147 rb_int_equal(VALUE x, VALUE y)
4148{
4149 if (FIXNUM_P(x)) {
4150 return fix_equal(x, y);
4151 }
4152 else if (RB_TYPE_P(x, T_BIGNUM)) {
4153 return rb_big_eq(x, y);
4154 }
4155 return Qnil;
4156}
4157
4158/*
4159 * Document-method: Integer#<=>
4160 * call-seq:
4161 * int <=> numeric -> -1, 0, +1, or nil
4162 *
4163 * Comparison---Returns -1, 0, or +1 depending on whether +int+ is
4164 * less than, equal to, or greater than +numeric+.
4165 *
4166 * This is the basis for the tests in the Comparable module.
4167 *
4168 * +nil+ is returned if the two values are incomparable.
4169 */
4170
4171static VALUE
4172fix_cmp(VALUE x, VALUE y)
4173{
4174 if (x == y) return INT2FIX(0);
4175 if (FIXNUM_P(y)) {
4176 if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1);
4177 return INT2FIX(-1);
4178 }
4179 else if (RB_TYPE_P(y, T_BIGNUM)) {
4180 VALUE cmp = rb_big_cmp(y, x);
4181 switch (cmp) {
4182 case INT2FIX(+1): return INT2FIX(-1);
4183 case INT2FIX(-1): return INT2FIX(+1);
4184 }
4185 return cmp;
4186 }
4187 else if (RB_TYPE_P(y, T_FLOAT)) {
4188 return rb_integer_float_cmp(x, y);
4189 }
4190 else {
4191 return rb_num_coerce_cmp(x, y, id_cmp);
4192 }
4193}
4194
4195 VALUE
4196 rb_int_cmp(VALUE x, VALUE y)
4197{
4198 if (FIXNUM_P(x)) {
4199 return fix_cmp(x, y);
4200 }
4201 else if (RB_TYPE_P(x, T_BIGNUM)) {
4202 return rb_big_cmp(x, y);
4203 }
4204 else {
4205 rb_raise(rb_eNotImpError, "need to define `<=>' in %s", rb_obj_classname(x));
4206 }
4207}
4208
4209/*
4210 * Document-method: Integer#>
4211 * call-seq:
4212 * int > real -> true or false
4213 *
4214 * Returns +true+ if the value of +int+ is greater than that of +real+.
4215 */
4216
4217static VALUE
4218fix_gt(VALUE x, VALUE y)
4219{
4220 if (FIXNUM_P(y)) {
4221 if (FIX2LONG(x) > FIX2LONG(y)) return Qtrue;
4222 return Qfalse;
4223 }
4224 else if (RB_TYPE_P(y, T_BIGNUM)) {
4225 return rb_big_cmp(y, x) == INT2FIX(-1) ? Qtrue : Qfalse;
4226 }
4227 else if (RB_TYPE_P(y, T_FLOAT)) {
4228 return rb_integer_float_cmp(x, y) == INT2FIX(1) ? Qtrue : Qfalse;
4229 }
4230 else {
4231 return rb_num_coerce_relop(x, y, '>');
4232 }
4233}
4234
4235 VALUE
4236 rb_int_gt(VALUE x, VALUE y)
4237{
4238 if (FIXNUM_P(x)) {
4239 return fix_gt(x, y);
4240 }
4241 else if (RB_TYPE_P(x, T_BIGNUM)) {
4242 return rb_big_gt(x, y);
4243 }
4244 return Qnil;
4245}
4246
4247/*
4248 * Document-method: Integer#>=
4249 * call-seq:
4250 * int >= real -> true or false
4251 *
4252 * Returns +true+ if the value of +int+ is greater than or equal to that of
4253 * +real+.
4254 */
4255
4256static VALUE
4257fix_ge(VALUE x, VALUE y)
4258{
4259 if (FIXNUM_P(y)) {
4260 if (FIX2LONG(x) >= FIX2LONG(y)) return Qtrue;
4261 return Qfalse;
4262 }
4263 else if (RB_TYPE_P(y, T_BIGNUM)) {
4264 return rb_big_cmp(y, x) != INT2FIX(+1) ? Qtrue : Qfalse;
4265 }
4266 else if (RB_TYPE_P(y, T_FLOAT)) {
4267 VALUE rel = rb_integer_float_cmp(x, y);
4268 return rel == INT2FIX(1) || rel == INT2FIX(0) ? Qtrue : Qfalse;
4269 }
4270 else {
4271 return rb_num_coerce_relop(x, y, idGE);
4272 }
4273}
4274
4275 VALUE
4276 rb_int_ge(VALUE x, VALUE y)
4277{
4278 if (FIXNUM_P(x)) {
4279 return fix_ge(x, y);
4280 }
4281 else if (RB_TYPE_P(x, T_BIGNUM)) {
4282 return rb_big_ge(x, y);
4283 }
4284 return Qnil;
4285}
4286
4287/*
4288 * Document-method: Integer#<
4289 * call-seq:
4290 * int < real -> true or false
4291 *
4292 * Returns +true+ if the value of +int+ is less than that of +real+.
4293 */
4294
4295static VALUE
4296fix_lt(VALUE x, VALUE y)
4297{
4298 if (FIXNUM_P(y)) {
4299 if (FIX2LONG(x) < FIX2LONG(y)) return Qtrue;
4300 return Qfalse;
4301 }
4302 else if (RB_TYPE_P(y, T_BIGNUM)) {
4303 return rb_big_cmp(y, x) == INT2FIX(+1) ? Qtrue : Qfalse;
4304 }
4305 else if (RB_TYPE_P(y, T_FLOAT)) {
4306 return rb_integer_float_cmp(x, y) == INT2FIX(-1) ? Qtrue : Qfalse;
4307 }
4308 else {
4309 return rb_num_coerce_relop(x, y, '<');
4310 }
4311}
4312
4313static VALUE
4314int_lt(VALUE x, VALUE y)
4315{
4316 if (FIXNUM_P(x)) {
4317 return fix_lt(x, y);
4318 }
4319 else if (RB_TYPE_P(x, T_BIGNUM)) {
4320 return rb_big_lt(x, y);
4321 }
4322 return Qnil;
4323}
4324
4325/*
4326 * Document-method: Integer#<=
4327 * call-seq:
4328 * int <= real -> true or false
4329 *
4330 * Returns +true+ if the value of +int+ is less than or equal to that of
4331 * +real+.
4332 */
4333
4334static VALUE
4335fix_le(VALUE x, VALUE y)
4336{
4337 if (FIXNUM_P(y)) {
4338 if (FIX2LONG(x) <= FIX2LONG(y)) return Qtrue;
4339 return Qfalse;
4340 }
4341 else if (RB_TYPE_P(y, T_BIGNUM)) {
4342 return rb_big_cmp(y, x) != INT2FIX(-1) ? Qtrue : Qfalse;
4343 }
4344 else if (RB_TYPE_P(y, T_FLOAT)) {
4345 VALUE rel = rb_integer_float_cmp(x, y);
4346 return rel == INT2FIX(-1) || rel == INT2FIX(0) ? Qtrue : Qfalse;
4347 }
4348 else {
4349 return rb_num_coerce_relop(x, y, idLE);
4350 }
4351}
4352
4353static VALUE
4354int_le(VALUE x, VALUE y)
4355{
4356 if (FIXNUM_P(x)) {
4357 return fix_le(x, y);
4358 }
4359 else if (RB_TYPE_P(x, T_BIGNUM)) {
4360 return rb_big_le(x, y);
4361 }
4362 return Qnil;
4363}
4364
4365static VALUE
4366fix_comp(VALUE num)
4367{
4368 return ~num | FIXNUM_FLAG;
4369}
4370
4371 VALUE
4372 rb_int_comp(VALUE num)
4373{
4374 if (FIXNUM_P(num)) {
4375 return fix_comp(num);
4376 }
4377 else if (RB_TYPE_P(num, T_BIGNUM)) {
4378 return rb_big_comp(num);
4379 }
4380 return Qnil;
4381}
4382
4383static VALUE
4384num_funcall_bit_1(VALUE y, VALUE arg, int recursive)
4385{
4386 ID func = (ID)((VALUE *)arg)[0];
4387 VALUE x = ((VALUE *)arg)[1];
4388 if (recursive) {
4389 num_funcall_op_1_recursion(x, func, y);
4390 }
4391 return rb_check_funcall(x, func, 1, &y);
4392}
4393
4394 VALUE
4395 rb_num_coerce_bit(VALUE x, VALUE y, ID func)
4396{
4397 VALUE ret, args[3];
4398
4399 args[0] = (VALUE)func;
4400 args[1] = x;
4401 args[2] = y;
4402 do_coerce(&args[1], &args[2], TRUE);
4403 ret = rb_exec_recursive_paired(num_funcall_bit_1,
4404 args[2], args[1], (VALUE)args);
4405 if (ret == Qundef) {
4406 /* show the original object, not coerced object */
4407 coerce_failed(x, y);
4408 }
4409 return ret;
4410}
4411
4412/*
4413 * Document-method: Integer#&
4414 * call-seq:
4415 * int & other_int -> integer
4416 *
4417 * Bitwise AND.
4418 */
4419
4420static VALUE
4421fix_and(VALUE x, VALUE y)
4422{
4423 if (FIXNUM_P(y)) {
4424 long val = FIX2LONG(x) & FIX2LONG(y);
4425 return LONG2NUM(val);
4426 }
4427
4428 if (RB_TYPE_P(y, T_BIGNUM)) {
4429 return rb_big_and(y, x);
4430 }
4431
4432 return rb_num_coerce_bit(x, y, '&');
4433}
4434
4435 VALUE
4436 rb_int_and(VALUE x, VALUE y)
4437{
4438 if (FIXNUM_P(x)) {
4439 return fix_and(x, y);
4440 }
4441 else if (RB_TYPE_P(x, T_BIGNUM)) {
4442 return rb_big_and(x, y);
4443 }
4444 return Qnil;
4445}
4446
4447/*
4448 * Document-method: Integer#|
4449 * call-seq:
4450 * int | other_int -> integer
4451 *
4452 * Bitwise OR.
4453 */
4454
4455static VALUE
4456fix_or(VALUE x, VALUE y)
4457{
4458 if (FIXNUM_P(y)) {
4459 long val = FIX2LONG(x) | FIX2LONG(y);
4460 return LONG2NUM(val);
4461 }
4462
4463 if (RB_TYPE_P(y, T_BIGNUM)) {
4464 return rb_big_or(y, x);
4465 }
4466
4467 return rb_num_coerce_bit(x, y, '|');
4468}
4469
4470static VALUE
4471int_or(VALUE x, VALUE y)
4472{
4473 if (FIXNUM_P(x)) {
4474 return fix_or(x, y);
4475 }
4476 else if (RB_TYPE_P(x, T_BIGNUM)) {
4477 return rb_big_or(x, y);
4478 }
4479 return Qnil;
4480}
4481
4482/*
4483 * Document-method: Integer#^
4484 * call-seq:
4485 * int ^ other_int -> integer
4486 *
4487 * Bitwise EXCLUSIVE OR.
4488 */
4489
4490static VALUE
4491fix_xor(VALUE x, VALUE y)
4492{
4493 if (FIXNUM_P(y)) {
4494 long val = FIX2LONG(x) ^ FIX2LONG(y);
4495 return LONG2NUM(val);
4496 }
4497
4498 if (RB_TYPE_P(y, T_BIGNUM)) {
4499 return rb_big_xor(y, x);
4500 }
4501
4502 return rb_num_coerce_bit(x, y, '^');
4503}
4504
4505static VALUE
4506int_xor(VALUE x, VALUE y)
4507{
4508 if (FIXNUM_P(x)) {
4509 return fix_xor(x, y);
4510 }
4511 else if (RB_TYPE_P(x, T_BIGNUM)) {
4512 return rb_big_xor(x, y);
4513 }
4514 return Qnil;
4515}
4516
4517/*
4518 * Document-method: Integer#<<
4519 * call-seq:
4520 * int << count -> integer
4521 *
4522 * Returns +int+ shifted left +count+ positions, or right if +count+
4523 * is negative.
4524 */
4525
4526static VALUE
4527rb_fix_lshift(VALUE x, VALUE y)
4528{
4529 long val, width;
4530
4531 val = NUM2LONG(x);
4532 if (!val) return (rb_to_int(y), INT2FIX(0));
4533 if (!FIXNUM_P(y))
4534 return rb_big_lshift(rb_int2big(val), y);
4535 width = FIX2LONG(y);
4536 if (width < 0)
4537 return fix_rshift(val, (unsigned long)-width);
4538 return fix_lshift(val, width);
4539}
4540
4541static VALUE
4542fix_lshift(long val, unsigned long width)
4543{
4544 if (width > (SIZEOF_LONG*CHAR_BIT-1)
4545 || ((unsigned long)val)>>(SIZEOF_LONG*CHAR_BIT-1-width) > 0) {
4546 return rb_big_lshift(rb_int2big(val), ULONG2NUM(width));
4547 }
4548 val = val << width;
4549 return LONG2NUM(val);
4550}
4551
4552 VALUE
4553 rb_int_lshift(VALUE x, VALUE y)
4554{
4555 if (FIXNUM_P(x)) {
4556 return rb_fix_lshift(x, y);
4557 }
4558 else if (RB_TYPE_P(x, T_BIGNUM)) {
4559 return rb_big_lshift(x, y);
4560 }
4561 return Qnil;
4562}
4563
4564/*
4565 * Document-method: Integer#>>
4566 * call-seq:
4567 * int >> count -> integer
4568 *
4569 * Returns +int+ shifted right +count+ positions, or left if +count+
4570 * is negative.
4571 */
4572
4573static VALUE
4574rb_fix_rshift(VALUE x, VALUE y)
4575{
4576 long i, val;
4577
4578 val = FIX2LONG(x);
4579 if (!val) return (rb_to_int(y), INT2FIX(0));
4580 if (!FIXNUM_P(y))
4581 return rb_big_rshift(rb_int2big(val), y);
4582 i = FIX2LONG(y);
4583 if (i == 0) return x;
4584 if (i < 0)
4585 return fix_lshift(val, (unsigned long)-i);
4586 return fix_rshift(val, i);
4587}
4588
4589static VALUE
4590fix_rshift(long val, unsigned long i)
4591{
4592 if (i >= sizeof(long)*CHAR_BIT-1) {
4593 if (val < 0) return INT2FIX(-1);
4594 return INT2FIX(0);
4595 }
4596 val = RSHIFT(val, i);
4597 return LONG2FIX(val);
4598}
4599
4600static VALUE
4601rb_int_rshift(VALUE x, VALUE y)
4602{
4603 if (FIXNUM_P(x)) {
4604 return rb_fix_rshift(x, y);
4605 }
4606 else if (RB_TYPE_P(x, T_BIGNUM)) {
4607 return rb_big_rshift(x, y);
4608 }
4609 return Qnil;
4610}
4611
4612 MJIT_FUNC_EXPORTED VALUE
4613 rb_fix_aref(VALUE fix, VALUE idx)
4614{
4615 long val = FIX2LONG(fix);
4616 long i;
4617
4618 idx = rb_to_int(idx);
4619 if (!FIXNUM_P(idx)) {
4620 idx = rb_big_norm(idx);
4621 if (!FIXNUM_P(idx)) {
4622 if (!BIGNUM_SIGN(idx) || val >= 0)
4623 return INT2FIX(0);
4624 return INT2FIX(1);
4625 }
4626 }
4627 i = FIX2LONG(idx);
4628
4629 if (i < 0) return INT2FIX(0);
4630 if (SIZEOF_LONG*CHAR_BIT-1 <= i) {
4631 if (val < 0) return INT2FIX(1);
4632 return INT2FIX(0);
4633 }
4634 if (val & (1L<<i))
4635 return INT2FIX(1);
4636 return INT2FIX(0);
4637}
4638
4639
4640/* copied from "r_less" in range.c */
4641/* compares _a_ and _b_ and returns:
4642 * < 0: a < b
4643 * = 0: a = b
4644 * > 0: a > b or non-comparable
4645 */
4646static int
4647compare_indexes(VALUE a, VALUE b)
4648{
4649 VALUE r = rb_funcall(a, id_cmp, 1, b);
4650
4651 if (NIL_P(r))
4652 return INT_MAX;
4653 return rb_cmpint(r, a, b);
4654}
4655
4656static VALUE
4657generate_mask(VALUE len)
4658{
4659 return rb_int_minus(rb_int_lshift(INT2FIX(1), len), INT2FIX(1));
4660}
4661
4662static VALUE
4663int_aref1(VALUE num, VALUE arg)
4664{
4665 VALUE orig_num = num, beg, end;
4666 int excl;
4667
4668 if (rb_range_values(arg, &beg, &end, &excl)) {
4669 if (NIL_P(beg)) {
4670 /* beginless range */
4671 if (!RTEST(num_negative_p(end))) {
4672 if (!excl) end = rb_int_plus(end, INT2FIX(1));
4673 VALUE mask = generate_mask(end);
4674 if (RTEST(int_zero_p(rb_int_and(num, mask)))) {
4675 return INT2FIX(0);
4676 }
4677 else {
4678 rb_raise(rb_eArgError, "The beginless range for Integer#[] results in infinity");
4679 }
4680 }
4681 else {
4682 return INT2FIX(0);
4683 }
4684 }
4685 num = rb_int_rshift(num, beg);
4686
4687 int cmp = compare_indexes(beg, end);
4688 if (!NIL_P(end) && cmp < 0) {
4689 VALUE len = rb_int_minus(end, beg);
4690 if (!excl) len = rb_int_plus(len, INT2FIX(1));
4691 VALUE mask = generate_mask(len);
4692 num = rb_int_and(num, mask);
4693 }
4694 else if (cmp == 0) {
4695 if (excl) return INT2FIX(0);
4696 num = orig_num;
4697 arg = beg;
4698 goto one_bit;
4699 }
4700 return num;
4701 }
4702
4703one_bit:
4704 if (FIXNUM_P(num)) {
4705 return rb_fix_aref(num, arg);
4706 }
4707 else if (RB_TYPE_P(num, T_BIGNUM)) {
4708 return rb_big_aref(num, arg);
4709 }
4710 return Qnil;
4711}
4712
4713static VALUE
4714int_aref2(VALUE num, VALUE beg, VALUE len)
4715{
4716 num = rb_int_rshift(num, beg);
4717 VALUE mask = generate_mask(len);
4718 num = rb_int_and(num, mask);
4719 return num;
4720}
4721
4722/*
4723 * Document-method: Integer#[]
4724 * call-seq:
4725 * int[n] -> 0, 1
4726 * int[n, m] -> num
4727 * int[range] -> num
4728 *
4729 * Bit Reference---Returns the <code>n</code>th bit in the
4730 * binary representation of +int+, where <code>int[0]</code>
4731 * is the least significant bit.
4732 *
4733 * a = 0b11001100101010
4734 * 30.downto(0) {|n| print a[n] }
4735 * #=> 0000000000000000011001100101010
4736 *
4737 * a = 9**15
4738 * 50.downto(0) {|n| print a[n] }
4739 * #=> 000101110110100000111000011110010100111100010111001
4740 *
4741 * In principle, <code>n[i]</code> is equivalent to <code>(n >> i) & 1</code>.
4742 * Thus, any negative index always returns zero:
4743 *
4744 * p 255[-1] #=> 0
4745 *
4746 * Range operations <code>n[i, len]</code> and <code>n[i..j]</code>
4747 * are naturally extended.
4748 *
4749 * * <code>n[i, len]</code> equals to <code>(n >> i) & ((1 << len) - 1)</code>.
4750 * * <code>n[i..j]</code> equals to <code>(n >> i) & ((1 << (j - i + 1)) - 1)</code>.
4751 * * <code>n[i...j]</code> equals to <code>(n >> i) & ((1 << (j - i)) - 1)</code>.
4752 * * <code>n[i..]</code> equals to <code>(n >> i)</code>.
4753 * * <code>n[..j]</code> is zero if <code>n & ((1 << (j + 1)) - 1)</code> is zero. Otherwise, raises an ArgumentError.
4754 * * <code>n[...j]</code> is zero if <code>n & ((1 << j) - 1)</code> is zero. Otherwise, raises an ArgumentError.
4755 *
4756 * Note that range operation may exhaust memory.
4757 * For example, <code>-1[0, 1000000000000]</code> will raise NoMemoryError.
4758 */
4759
4760static VALUE
4761int_aref(int const argc, VALUE * const argv, VALUE const num)
4762{
4763 rb_check_arity(argc, 1, 2);
4764 if (argc == 2) {
4765 return int_aref2(num, argv[0], argv[1]);
4766 }
4767 return int_aref1(num, argv[0]);
4768
4769 return Qnil;
4770}
4771
4772/*
4773 * Document-method: Integer#to_f
4774 * call-seq:
4775 * int.to_f -> float
4776 *
4777 * Converts +int+ to a Float. If +int+ doesn't fit in a Float,
4778 * the result is infinity.
4779 */
4780
4781static VALUE
4782int_to_f(VALUE num)
4783{
4784 double val;
4785
4786 if (FIXNUM_P(num)) {
4787 val = (double)FIX2LONG(num);
4788 }
4789 else if (RB_TYPE_P(num, T_BIGNUM)) {
4790 val = rb_big2dbl(num);
4791 }
4792 else {
4793 rb_raise(rb_eNotImpError, "Unknown subclass for to_f: %s", rb_obj_classname(num));
4794 }
4795
4796 return DBL2NUM(val);
4797}
4798
4799/*
4800 * Document-method: Integer#abs
4801 * Document-method: Integer#magnitude
4802 * call-seq:
4803 * int.abs -> integer
4804 * int.magnitude -> integer
4805 *
4806 * Returns the absolute value of +int+.
4807 *
4808 * (-12345).abs #=> 12345
4809 * -12345.abs #=> 12345
4810 * 12345.abs #=> 12345
4811 *
4812 * Integer#magnitude is an alias for Integer#abs.
4813 */
4814
4815static VALUE
4816fix_abs(VALUE fix)
4817{
4818 long i = FIX2LONG(fix);
4819
4820 if (i < 0) i = -i;
4821
4822 return LONG2NUM(i);
4823}
4824
4825 VALUE
4826 rb_int_abs(VALUE num)
4827{
4828 if (FIXNUM_P(num)) {
4829 return fix_abs(num);
4830 }
4831 else if (RB_TYPE_P(num, T_BIGNUM)) {
4832 return rb_big_abs(num);
4833 }
4834 return Qnil;
4835}
4836
4837/*
4838 * Document-method: Integer#size
4839 * call-seq:
4840 * int.size -> int
4841 *
4842 * Returns the number of bytes in the machine representation of +int+
4843 * (machine dependent).
4844 *
4845 * 1.size #=> 8
4846 * -1.size #=> 8
4847 * 2147483647.size #=> 8
4848 * (256**10 - 1).size #=> 10
4849 * (256**20 - 1).size #=> 20
4850 * (256**40 - 1).size #=> 40
4851 */
4852
4853static VALUE
4854fix_size(VALUE fix)
4855{
4856 return INT2FIX(sizeof(long));
4857}
4858
4859static VALUE
4860int_size(VALUE num)
4861{
4862 if (FIXNUM_P(num)) {
4863 return fix_size(num);
4864 }
4865 else if (RB_TYPE_P(num, T_BIGNUM)) {
4866 return rb_big_size_m(num);
4867 }
4868 return Qnil;
4869}
4870
4871static VALUE
4872rb_fix_bit_length(VALUE fix)
4873{
4874 long v = FIX2LONG(fix);
4875 if (v < 0)
4876 v = ~v;
4877 return LONG2FIX(bit_length(v));
4878}
4879
4880 VALUE
4881 rb_int_bit_length(VALUE num)
4882{
4883 if (FIXNUM_P(num)) {
4884 return rb_fix_bit_length(num);
4885 }
4886 else if (RB_TYPE_P(num, T_BIGNUM)) {
4887 return rb_big_bit_length(num);
4888 }
4889 return Qnil;
4890}
4891
4892/*
4893 * Document-method: Integer#digits
4894 * call-seq:
4895 * int.digits -> array
4896 * int.digits(base) -> array
4897 *
4898 * Returns the digits of +int+'s place-value representation
4899 * with radix +base+ (default: 10).
4900 * The digits are returned as an array with the least significant digit
4901 * as the first array element.
4902 *
4903 * +base+ must be greater than or equal to 2.
4904 *
4905 * 12345.digits #=> [5, 4, 3, 2, 1]
4906 * 12345.digits(7) #=> [4, 6, 6, 0, 5]
4907 * 12345.digits(100) #=> [45, 23, 1]
4908 *
4909 * -12345.digits(7) #=> Math::DomainError
4910 */
4911
4912static VALUE
4913rb_fix_digits(VALUE fix, long base)
4914{
4915 VALUE digits;
4916 long x = FIX2LONG(fix);
4917
4918 assert(x >= 0);
4919
4920 if (base < 2)
4921 rb_raise(rb_eArgError, "invalid radix %ld", base);
4922
4923 if (x == 0)
4924 return rb_ary_new_from_args(1, INT2FIX(0));
4925
4926 digits = rb_ary_new();
4927 while (x > 0) {
4928 long q = x % base;
4929 rb_ary_push(digits, LONG2NUM(q));
4930 x /= base;
4931 }
4932
4933 return digits;
4934}
4935
4936static VALUE
4937rb_int_digits_bigbase(VALUE num, VALUE base)
4938{
4939 VALUE digits;
4940
4941 assert(!rb_num_negative_p(num));
4942
4943 if (RB_TYPE_P(base, T_BIGNUM))
4944 base = rb_big_norm(base);
4945
4946 if (FIXNUM_P(base) && FIX2LONG(base) < 2)
4947 rb_raise(rb_eArgError, "invalid radix %ld", FIX2LONG(base));
4948 else if (RB_TYPE_P(base, T_BIGNUM) && BIGNUM_NEGATIVE_P(base))
4949 rb_raise(rb_eArgError, "negative radix");
4950
4951 if (FIXNUM_P(base) && FIXNUM_P(num))
4952 return rb_fix_digits(num, FIX2LONG(base));
4953
4954 if (FIXNUM_P(num))
4955 return rb_ary_new_from_args(1, num);
4956
4957 digits = rb_ary_new();
4958 while (!FIXNUM_P(num) || FIX2LONG(num) > 0) {
4959 VALUE qr = rb_int_divmod(num, base);
4960 rb_ary_push(digits, RARRAY_AREF(qr, 1));
4961 num = RARRAY_AREF(qr, 0);
4962 }
4963
4964 return digits;
4965}
4966
4967static VALUE
4968rb_int_digits(int argc, VALUE *argv, VALUE num)
4969{
4970 VALUE base_value;
4971 long base;
4972
4973 if (rb_num_negative_p(num))
4974 rb_raise(rb_eMathDomainError, "out of domain");
4975
4976 if (rb_check_arity(argc, 0, 1)) {
4977 base_value = rb_to_int(argv[0]);
4978 if (!RB_INTEGER_TYPE_P(base_value))
4979 rb_raise(rb_eTypeError, "wrong argument type %s (expected Integer)",
4980 rb_obj_classname(argv[0]));
4981 if (RB_TYPE_P(base_value, T_BIGNUM))
4982 return rb_int_digits_bigbase(num, base_value);
4983
4984 base = FIX2LONG(base_value);
4985 if (base < 0)
4986 rb_raise(rb_eArgError, "negative radix");
4987 else if (base < 2)
4988 rb_raise(rb_eArgError, "invalid radix %ld", base);
4989 }
4990 else
4991 base = 10;
4992
4993 if (FIXNUM_P(num))
4994 return rb_fix_digits(num, base);
4995 else if (RB_TYPE_P(num, T_BIGNUM))
4996 return rb_int_digits_bigbase(num, LONG2FIX(base));
4997
4998 return Qnil;
4999}
5000
5001/*
5002 * Document-method: Integer#upto
5003 * call-seq:
5004 * int.upto(limit) {|i| block } -> self
5005 * int.upto(limit) -> an_enumerator
5006 *
5007 * Iterates the given block, passing in integer values from +int+ up to and
5008 * including +limit+.
5009 *
5010 * If no block is given, an Enumerator is returned instead.
5011 *
5012 * 5.upto(10) {|i| print i, " " } #=> 5 6 7 8 9 10
5013 */
5014
5015static VALUE
5016int_upto_size(VALUE from, VALUE args, VALUE eobj)
5017{
5018 return ruby_num_interval_step_size(from, RARRAY_AREF(args, 0), INT2FIX(1), FALSE);
5019}
5020
5021static VALUE
5022int_upto(VALUE from, VALUE to)
5023{
5024 RETURN_SIZED_ENUMERATOR(from, 1, &to, int_upto_size);
5025 if (FIXNUM_P(from) && FIXNUM_P(to)) {
5026 long i, end;
5027
5028 end = FIX2LONG(to);
5029 for (i = FIX2LONG(from); i <= end; i++) {
5030 rb_yield(LONG2FIX(i));
5031 }
5032 }
5033 else {
5034 VALUE i = from, c;
5035
5036 while (!(c = rb_funcall(i, '>', 1, to))) {
5037 rb_yield(i);
5038 i = rb_funcall(i, '+', 1, INT2FIX(1));
5039 }
5040 ensure_cmp(c, i, to);
5041 }
5042 return from;
5043}
5044
5045/*
5046 * Document-method: Integer#downto
5047 * call-seq:
5048 * int.downto(limit) {|i| block } -> self
5049 * int.downto(limit) -> an_enumerator
5050 *
5051 * Iterates the given block, passing in decreasing values from +int+ down to
5052 * and including +limit+.
5053 *
5054 * If no block is given, an Enumerator is returned instead.
5055 *
5056 * 5.downto(1) { |n| print n, ".. " }
5057 * puts "Liftoff!"
5058 * #=> "5.. 4.. 3.. 2.. 1.. Liftoff!"
5059 */
5060
5061static VALUE
5062int_downto_size(VALUE from, VALUE args, VALUE eobj)
5063{
5064 return ruby_num_interval_step_size(from, RARRAY_AREF(args, 0), INT2FIX(-1), FALSE);
5065}
5066
5067static VALUE
5068int_downto(VALUE from, VALUE to)
5069{
5070 RETURN_SIZED_ENUMERATOR(from, 1, &to, int_downto_size);
5071 if (FIXNUM_P(from) && FIXNUM_P(to)) {
5072 long i, end;
5073
5074 end = FIX2LONG(to);
5075 for (i=FIX2LONG(from); i >= end; i--) {
5076 rb_yield(LONG2FIX(i));
5077 }
5078 }
5079 else {
5080 VALUE i = from, c;
5081
5082 while (!(c = rb_funcall(i, '<', 1, to))) {
5083 rb_yield(i);
5084 i = rb_funcall(i, '-', 1, INT2FIX(1));
5085 }
5086 if (NIL_P(c)) rb_cmperr(i, to);
5087 }
5088 return from;
5089}
5090
5091/*
5092 * Document-method: Integer#times
5093 * call-seq:
5094 * int.times {|i| block } -> self
5095 * int.times -> an_enumerator
5096 *
5097 * Iterates the given block +int+ times, passing in values from zero to
5098 * <code>int - 1</code>.
5099 *
5100 * If no block is given, an Enumerator is returned instead.
5101 *
5102 * 5.times {|i| print i, " " } #=> 0 1 2 3 4
5103 */
5104
5105static VALUE
5106int_dotimes_size(VALUE num, VALUE args, VALUE eobj)
5107{
5108 if (FIXNUM_P(num)) {
5109 if (NUM2LONG(num) <= 0) return INT2FIX(0);
5110 }
5111 else {
5112 if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) return INT2FIX(0);
5113 }
5114 return num;
5115}
5116
5117static VALUE
5118int_dotimes(VALUE num)
5119{
5120 RETURN_SIZED_ENUMERATOR(num, 0, 0, int_dotimes_size);
5121
5122 if (FIXNUM_P(num)) {
5123 long i, end;
5124
5125 end = FIX2LONG(num);
5126 for (i=0; i<end; i++) {
5127 rb_yield_1(LONG2FIX(i));
5128 }
5129 }
5130 else {
5131 VALUE i = INT2FIX(0);
5132
5133 for (;;) {
5134 if (!RTEST(rb_funcall(i, '<', 1, num))) break;
5135 rb_yield(i);
5136 i = rb_funcall(i, '+', 1, INT2FIX(1));
5137 }
5138 }
5139 return num;
5140}
5141
5142/*
5143 * Document-method: Integer#round
5144 * call-seq:
5145 * int.round([ndigits] [, half: mode]) -> integer or float
5146 *
5147 * Returns +int+ rounded to the nearest value with
5148 * a precision of +ndigits+ decimal digits (default: 0).
5149 *
5150 * When the precision is negative, the returned value is an integer
5151 * with at least <code>ndigits.abs</code> trailing zeros.
5152 *
5153 * Returns +self+ when +ndigits+ is zero or positive.
5154 *
5155 * 1.round #=> 1
5156 * 1.round(2) #=> 1
5157 * 15.round(-1) #=> 20
5158 * (-15).round(-1) #=> -20
5159 *
5160 * The optional +half+ keyword argument is available
5161 * similar to Float#round.
5162 *
5163 * 25.round(-1, half: :up) #=> 30
5164 * 25.round(-1, half: :down) #=> 20
5165 * 25.round(-1, half: :even) #=> 20
5166 * 35.round(-1, half: :up) #=> 40
5167 * 35.round(-1, half: :down) #=> 30
5168 * 35.round(-1, half: :even) #=> 40
5169 * (-25).round(-1, half: :up) #=> -30
5170 * (-25).round(-1, half: :down) #=> -20
5171 * (-25).round(-1, half: :even) #=> -20
5172 */
5173
5174static VALUE
5175int_round(int argc, VALUE* argv, VALUE num)
5176{
5177 int ndigits;
5178 int mode;
5179 VALUE nd, opt;
5180
5181 if (!rb_scan_args(argc, argv, "01:", &nd, &opt)) return num;
5182 ndigits = NUM2INT(nd);
5183 mode = rb_num_get_rounding_option(opt);
5184 if (ndigits >= 0) {
5185 return num;
5186 }
5187 return rb_int_round(num, ndigits, mode);
5188}
5189
5190/*
5191 * Document-method: Integer#floor
5192 * call-seq:
5193 * int.floor([ndigits]) -> integer or float
5194 *
5195 * Returns the largest number less than or equal to +int+ with
5196 * a precision of +ndigits+ decimal digits (default: 0).
5197 *
5198 * When the precision is negative, the returned value is an integer
5199 * with at least <code>ndigits.abs</code> trailing zeros.
5200 *
5201 * Returns +self+ when +ndigits+ is zero or positive.
5202 *
5203 * 1.floor #=> 1
5204 * 1.floor(2) #=> 1
5205 * 18.floor(-1) #=> 10
5206 * (-18).floor(-1) #=> -20
5207 */
5208
5209static VALUE
5210int_floor(int argc, VALUE* argv, VALUE num)
5211{
5212 int ndigits;
5213
5214 if (!rb_check_arity(argc, 0, 1)) return num;
5215 ndigits = NUM2INT(argv[0]);
5216 if (ndigits >= 0) {
5217 return num;
5218 }
5219 return rb_int_floor(num, ndigits);
5220}
5221
5222/*
5223 * Document-method: Integer#ceil
5224 * call-seq:
5225 * int.ceil([ndigits]) -> integer or float
5226 *
5227 * Returns the smallest number greater than or equal to +int+ with
5228 * a precision of +ndigits+ decimal digits (default: 0).
5229 *
5230 * When the precision is negative, the returned value is an integer
5231 * with at least <code>ndigits.abs</code> trailing zeros.
5232 *
5233 * Returns +self+ when +ndigits+ is zero or positive.
5234 *
5235 * 1.ceil #=> 1
5236 * 1.ceil(2) #=> 1
5237 * 18.ceil(-1) #=> 20
5238 * (-18).ceil(-1) #=> -10
5239 */
5240
5241static VALUE
5242int_ceil(int argc, VALUE* argv, VALUE num)
5243{
5244 int ndigits;
5245
5246 if (!rb_check_arity(argc, 0, 1)) return num;
5247 ndigits = NUM2INT(argv[0]);
5248 if (ndigits >= 0) {
5249 return num;
5250 }
5251 return rb_int_ceil(num, ndigits);
5252}
5253
5254/*
5255 * Document-method: Integer#truncate
5256 * call-seq:
5257 * int.truncate([ndigits]) -> integer or float
5258 *
5259 * Returns +int+ truncated (toward zero) to
5260 * a precision of +ndigits+ decimal digits (default: 0).
5261 *
5262 * When the precision is negative, the returned value is an integer
5263 * with at least <code>ndigits.abs</code> trailing zeros.
5264 *
5265 * Returns +self+ when +ndigits+ is zero or positive.
5266 *
5267 * 1.truncate #=> 1
5268 * 1.truncate(2) #=> 1
5269 * 18.truncate(-1) #=> 10
5270 * (-18).truncate(-1) #=> -10
5271 */
5272
5273static VALUE
5274int_truncate(int argc, VALUE* argv, VALUE num)
5275{
5276 int ndigits;
5277
5278 if (!rb_check_arity(argc, 0, 1)) return num;
5279 ndigits = NUM2INT(argv[0]);
5280 if (ndigits >= 0) {
5281 return num;
5282 }
5283 return rb_int_truncate(num, ndigits);
5284}
5285
5286#define DEFINE_INT_SQRT(rettype, prefix, argtype) \
5287rettype \
5288prefix##_isqrt(argtype n) \
5289{ \
5290 if (!argtype##_IN_DOUBLE_P(n)) { \
5291 unsigned int b = bit_length(n); \
5292 argtype t; \
5293 rettype x = (rettype)(n >> (b/2+1)); \
5294 x |= ((rettype)1LU << (b-1)/2); \
5295 while ((t = n/x) < (argtype)x) x = (rettype)((x + t) >> 1); \
5296 return x; \
5297 } \
5298 return (rettype)sqrt(argtype##_TO_DOUBLE(n)); \
5299}
5300
5301#if SIZEOF_LONG*CHAR_BIT > DBL_MANT_DIG
5302# define RB_ULONG_IN_DOUBLE_P(n) ((n) < (1UL << DBL_MANT_DIG))
5303#else
5304# define RB_ULONG_IN_DOUBLE_P(n) 1
5305#endif
5306#define RB_ULONG_TO_DOUBLE(n) (double)(n)
5307#define RB_ULONG unsigned long
5308 DEFINE_INT_SQRT(unsigned long, rb_ulong, RB_ULONG)
5309
5310#if 2*SIZEOF_BDIGIT > SIZEOF_LONG
5311# if 2*SIZEOF_BDIGIT*CHAR_BIT > DBL_MANT_DIG
5312# define BDIGIT_DBL_IN_DOUBLE_P(n) ((n) < ((BDIGIT_DBL)1UL << DBL_MANT_DIG))
5313# else
5314# define BDIGIT_DBL_IN_DOUBLE_P(n) 1
5315# endif
5316# ifdef ULL_TO_DOUBLE
5317# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
5318# else
5319# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
5320# endif
5321 DEFINE_INT_SQRT(BDIGIT, rb_bdigit_dbl, BDIGIT_DBL)
5322#endif
5323
5324#define domain_error(msg) \
5325 rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
5326
5327 VALUE rb_big_isqrt(VALUE);
5328
5329/*
5330 * Document-method: Integer::sqrt
5331 * call-seq:
5332 * Integer.sqrt(n) -> integer
5333 *
5334 * Returns the integer square root of the non-negative integer +n+,
5335 * i.e. the largest non-negative integer less than or equal to the
5336 * square root of +n+.
5337 *
5338 * Integer.sqrt(0) #=> 0
5339 * Integer.sqrt(1) #=> 1
5340 * Integer.sqrt(24) #=> 4
5341 * Integer.sqrt(25) #=> 5
5342 * Integer.sqrt(10**400) #=> 10**200
5343 *
5344 * Equivalent to <code>Math.sqrt(n).floor</code>, except that
5345 * the result of the latter code may differ from the true value
5346 * due to the limited precision of floating point arithmetic.
5347 *
5348 * Integer.sqrt(10**46) #=> 100000000000000000000000
5349 * Math.sqrt(10**46).floor #=> 99999999999999991611392 (!)
5350 *
5351 * If +n+ is not an Integer, it is converted to an Integer first.
5352 * If +n+ is negative, a Math::DomainError is raised.
5353 */
5354
5355static VALUE
5356rb_int_s_isqrt(VALUE self, VALUE num)
5357{
5358 unsigned long n, sq;
5359 num = rb_to_int(num);
5360 if (FIXNUM_P(num)) {
5361 if (FIXNUM_NEGATIVE_P(num)) {
5362 domain_error("isqrt");
5363 }
5364 n = FIX2ULONG(num);
5365 sq = rb_ulong_isqrt(n);
5366 return LONG2FIX(sq);
5367 }
5368 else {
5369 size_t biglen;
5370 if (RBIGNUM_NEGATIVE_P(num)) {
5371 domain_error("isqrt");
5372 }
5373 biglen = BIGNUM_LEN(num);
5374 if (biglen == 0) return INT2FIX(0);
5375#if SIZEOF_BDIGIT <= SIZEOF_LONG
5376 /* short-circuit */
5377 if (biglen == 1) {
5378 n = BIGNUM_DIGITS(num)[0];
5379 sq = rb_ulong_isqrt(n);
5380 return ULONG2NUM(sq);
5381 }
5382#endif
5383 return rb_big_isqrt(num);
5384 }
5385}
5386
5387/*
5388 * Document-class: ZeroDivisionError
5389 *
5390 * Raised when attempting to divide an integer by 0.
5391 *
5392 * 42 / 0 #=> ZeroDivisionError: divided by 0
5393 *
5394 * Note that only division by an exact 0 will raise the exception:
5395 *
5396 * 42 / 0.0 #=> Float::INFINITY
5397 * 42 / -0.0 #=> -Float::INFINITY
5398 * 0 / 0.0 #=> NaN
5399 */
5400
5401/*
5402 * Document-class: FloatDomainError
5403 *
5404 * Raised when attempting to convert special float values (in particular
5405 * +Infinity+ or +NaN+) to numerical classes which don't support them.
5406 *
5407 * Float::INFINITY.to_r #=> FloatDomainError: Infinity
5408 */
5409
5410/*
5411 * Document-class: Numeric
5412 *
5413 * Numeric is the class from which all higher-level numeric classes should inherit.
5414 *
5415 * Numeric allows instantiation of heap-allocated objects. Other core numeric classes such as
5416 * Integer are implemented as immediates, which means that each Integer is a single immutable
5417 * object which is always passed by value.
5418 *
5419 * a = 1
5420 * 1.object_id == a.object_id #=> true
5421 *
5422 * There can only ever be one instance of the integer +1+, for example. Ruby ensures this
5423 * by preventing instantiation. If duplication is attempted, the same instance is returned.
5424 *
5425 * Integer.new(1) #=> NoMethodError: undefined method `new' for Integer:Class
5426 * 1.dup #=> 1
5427 * 1.object_id == 1.dup.object_id #=> true
5428 *
5429 * For this reason, Numeric should be used when defining other numeric classes.
5430 *
5431 * Classes which inherit from Numeric must implement +coerce+, which returns a two-member
5432 * Array containing an object that has been coerced into an instance of the new class
5433 * and +self+ (see #coerce).
5434 *
5435 * Inheriting classes should also implement arithmetic operator methods (<code>+</code>,
5436 * <code>-</code>, <code>*</code> and <code>/</code>) and the <code><=></code> operator (see
5437 * Comparable). These methods may rely on +coerce+ to ensure interoperability with
5438 * instances of other numeric classes.
5439 *
5440 * class Tally < Numeric
5441 * def initialize(string)
5442 * @string = string
5443 * end
5444 *
5445 * def to_s
5446 * @string
5447 * end
5448 *
5449 * def to_i
5450 * @string.size
5451 * end
5452 *
5453 * def coerce(other)
5454 * [self.class.new('|' * other.to_i), self]
5455 * end
5456 *
5457 * def <=>(other)
5458 * to_i <=> other.to_i
5459 * end
5460 *
5461 * def +(other)
5462 * self.class.new('|' * (to_i + other.to_i))
5463 * end
5464 *
5465 * def -(other)
5466 * self.class.new('|' * (to_i - other.to_i))
5467 * end
5468 *
5469 * def *(other)
5470 * self.class.new('|' * (to_i * other.to_i))
5471 * end
5472 *
5473 * def /(other)
5474 * self.class.new('|' * (to_i / other.to_i))
5475 * end
5476 * end
5477 *
5478 * tally = Tally.new('||')
5479 * puts tally * 2 #=> "||||"
5480 * puts tally > 1 #=> true
5481 */
5482void
5483Init_Numeric(void)
5484{
5485#ifdef _UNICOSMP
5486 /* Turn off floating point exceptions for divide by zero, etc. */
5487 _set_Creg(0, 0);
5488#endif
5489 id_coerce = rb_intern_const("coerce");
5490 id_to = rb_intern_const("to");
5491 id_by = rb_intern_const("by");
5492
5493 rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
5494 rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError);
5495 rb_cNumeric = rb_define_class("Numeric", rb_cObject);
5496
5497 rb_define_method(rb_cNumeric, "singleton_method_added", num_sadded, 1);
5498 rb_include_module(rb_cNumeric, rb_mComparable);
5499 rb_define_method(rb_cNumeric, "coerce", num_coerce, 1);
5500 rb_define_method(rb_cNumeric, "clone", num_clone, -1);
5501 rb_define_method(rb_cNumeric, "dup", num_dup, 0);
5502
5503 rb_define_method(rb_cNumeric, "i", num_imaginary, 0);
5504 rb_define_method(rb_cNumeric, "+@", num_uplus, 0);
5505 rb_define_method(rb_cNumeric, "-@", num_uminus, 0);
5506 rb_define_method(rb_cNumeric, "<=>", num_cmp, 1);
5507 rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
5508 rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1);
5509 rb_define_method(rb_cNumeric, "div", num_div, 1);
5510 rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
5511 rb_define_method(rb_cNumeric, "%", num_modulo, 1);
5512 rb_define_method(rb_cNumeric, "modulo", num_modulo, 1);
5513 rb_define_method(rb_cNumeric, "remainder", num_remainder, 1);
5514 rb_define_method(rb_cNumeric, "abs", num_abs, 0);
5515 rb_define_method(rb_cNumeric, "magnitude", num_abs, 0);
5516 rb_define_method(rb_cNumeric, "to_int", num_to_int, 0);
5517
5518 rb_define_method(rb_cNumeric, "real?", num_real_p, 0);
5519 rb_define_method(rb_cNumeric, "integer?", num_int_p, 0);
5520 rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0);
5521 rb_define_method(rb_cNumeric, "nonzero?", num_nonzero_p, 0);
5522 rb_define_method(rb_cNumeric, "finite?", num_finite_p, 0);
5523 rb_define_method(rb_cNumeric, "infinite?", num_infinite_p, 0);
5524
5525 rb_define_method(rb_cNumeric, "floor", num_floor, -1);
5526 rb_define_method(rb_cNumeric, "ceil", num_ceil, -1);
5527 rb_define_method(rb_cNumeric, "round", num_round, -1);
5528 rb_define_method(rb_cNumeric, "truncate", num_truncate, -1);
5529 rb_define_method(rb_cNumeric, "step", num_step, -1);
5530 rb_define_method(rb_cNumeric, "positive?", num_positive_p, 0);
5531 rb_define_method(rb_cNumeric, "negative?", num_negative_p, 0);
5532
5533 rb_cInteger = rb_define_class("Integer", rb_cNumeric);
5534 rb_undef_alloc_func(rb_cInteger);
5535 rb_undef_method(CLASS_OF(rb_cInteger), "new");
5536 rb_define_singleton_method(rb_cInteger, "sqrt", rb_int_s_isqrt, 1);
5537
5538 rb_define_method(rb_cInteger, "to_s", int_to_s, -1);
5539 rb_define_alias(rb_cInteger, "inspect", "to_s");
5540 rb_define_method(rb_cInteger, "allbits?", int_allbits_p, 1);
5541 rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1);
5542 rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
5543 rb_define_method(rb_cInteger, "upto", int_upto, 1);
5544 rb_define_method(rb_cInteger, "downto", int_downto, 1);
5545 rb_define_method(rb_cInteger, "times", int_dotimes, 0);
5546 rb_define_method(rb_cInteger, "succ", int_succ, 0);
5547 rb_define_method(rb_cInteger, "next", int_succ, 0);
5548 rb_define_method(rb_cInteger, "pred", int_pred, 0);
5549 rb_define_method(rb_cInteger, "chr", int_chr, -1);
5550 rb_define_method(rb_cInteger, "to_f", int_to_f, 0);
5551 rb_define_method(rb_cInteger, "floor", int_floor, -1);
5552 rb_define_method(rb_cInteger, "ceil", int_ceil, -1);
5553 rb_define_method(rb_cInteger, "truncate", int_truncate, -1);
5554 rb_define_method(rb_cInteger, "round", int_round, -1);
5555 rb_define_method(rb_cInteger, "<=>", rb_int_cmp, 1);
5556
5557 rb_define_method(rb_cInteger, "+", rb_int_plus, 1);
5558 rb_define_method(rb_cInteger, "-", rb_int_minus, 1);
5559 rb_define_method(rb_cInteger, "*", rb_int_mul, 1);
5560 rb_define_method(rb_cInteger, "/", rb_int_div, 1);
5561 rb_define_method(rb_cInteger, "div", rb_int_idiv, 1);
5562 rb_define_method(rb_cInteger, "%", rb_int_modulo, 1);
5563 rb_define_method(rb_cInteger, "modulo", rb_int_modulo, 1);
5564 rb_define_method(rb_cInteger, "remainder", int_remainder, 1);
5565 rb_define_method(rb_cInteger, "divmod", rb_int_divmod, 1);
5566 rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1);
5567 rb_define_method(rb_cInteger, "**", rb_int_pow, 1);
5568
5569 rb_define_method(rb_cInteger, "pow", rb_int_powm, -1); /* in bignum.c */
5570
5571 rb_define_method(rb_cInteger, "===", rb_int_equal, 1);
5572 rb_define_method(rb_cInteger, "==", rb_int_equal, 1);
5573 rb_define_method(rb_cInteger, ">", rb_int_gt, 1);
5574 rb_define_method(rb_cInteger, ">=", rb_int_ge, 1);
5575 rb_define_method(rb_cInteger, "<", int_lt, 1);
5576 rb_define_method(rb_cInteger, "<=", int_le, 1);
5577
5578 rb_define_method(rb_cInteger, "&", rb_int_and, 1);
5579 rb_define_method(rb_cInteger, "|", int_or, 1);
5580 rb_define_method(rb_cInteger, "^", int_xor, 1);
5581 rb_define_method(rb_cInteger, "[]", int_aref, -1);
5582
5583 rb_define_method(rb_cInteger, "<<", rb_int_lshift, 1);
5584 rb_define_method(rb_cInteger, ">>", rb_int_rshift, 1);
5585
5586 rb_define_method(rb_cInteger, "size", int_size, 0);
5587 rb_define_method(rb_cInteger, "digits", rb_int_digits, -1);
5588
5589 /* An obsolete class, use Integer */
5590 rb_define_const(rb_cObject, "Fixnum", rb_cInteger);
5591 rb_deprecate_constant(rb_cObject, "Fixnum");
5592
5593 rb_cFloat = rb_define_class("Float", rb_cNumeric);
5594
5595 rb_undef_alloc_func(rb_cFloat);
5596 rb_undef_method(CLASS_OF(rb_cFloat), "new");
5597
5598 /*
5599 * The base of the floating point, or number of unique digits used to
5600 * represent the number.
5601 *
5602 * Usually defaults to 2 on most systems, which would represent a base-10 decimal.
5603 */
5604 rb_define_const(rb_cFloat, "RADIX", INT2FIX(FLT_RADIX));
5605 /*
5606 * The number of base digits for the +double+ data type.
5607 *
5608 * Usually defaults to 53.
5609 */
5610 rb_define_const(rb_cFloat, "MANT_DIG", INT2FIX(DBL_MANT_DIG));
5611 /*
5612 * The minimum number of significant decimal digits in a double-precision
5613 * floating point.
5614 *
5615 * Usually defaults to 15.
5616 */
5617 rb_define_const(rb_cFloat, "DIG", INT2FIX(DBL_DIG));
5618 /*
5619 * The smallest possible exponent value in a double-precision floating
5620 * point.
5621 *
5622 * Usually defaults to -1021.
5623 */
5624 rb_define_const(rb_cFloat, "MIN_EXP", INT2FIX(DBL_MIN_EXP));
5625 /*
5626 * The largest possible exponent value in a double-precision floating
5627 * point.
5628 *
5629 * Usually defaults to 1024.
5630 */
5631 rb_define_const(rb_cFloat, "MAX_EXP", INT2FIX(DBL_MAX_EXP));
5632 /*
5633 * The smallest negative exponent in a double-precision floating point
5634 * where 10 raised to this power minus 1.
5635 *
5636 * Usually defaults to -307.
5637 */
5638 rb_define_const(rb_cFloat, "MIN_10_EXP", INT2FIX(DBL_MIN_10_EXP));
5639 /*
5640 * The largest positive exponent in a double-precision floating point where
5641 * 10 raised to this power minus 1.
5642 *
5643 * Usually defaults to 308.
5644 */
5645 rb_define_const(rb_cFloat, "MAX_10_EXP", INT2FIX(DBL_MAX_10_EXP));
5646 /*
5647 * The smallest positive normalized number in a double-precision floating point.
5648 *
5649 * Usually defaults to 2.2250738585072014e-308.
5650 *
5651 * If the platform supports denormalized numbers,
5652 * there are numbers between zero and Float::MIN.
5653 * 0.0.next_float returns the smallest positive floating point number
5654 * including denormalized numbers.
5655 */
5656 rb_define_const(rb_cFloat, "MIN", DBL2NUM(DBL_MIN));
5657 /*
5658 * The largest possible integer in a double-precision floating point number.
5659 *
5660 * Usually defaults to 1.7976931348623157e+308.
5661 */
5662 rb_define_const(rb_cFloat, "MAX", DBL2NUM(DBL_MAX));
5663 /*
5664 * The difference between 1 and the smallest double-precision floating
5665 * point number greater than 1.
5666 *
5667 * Usually defaults to 2.2204460492503131e-16.
5668 */
5669 rb_define_const(rb_cFloat, "EPSILON", DBL2NUM(DBL_EPSILON));
5670 /*
5671 * An expression representing positive infinity.
5672 */
5673 rb_define_const(rb_cFloat, "INFINITY", DBL2NUM(HUGE_VAL));
5674 /*
5675 * An expression representing a value which is "not a number".
5676 */
5677 rb_define_const(rb_cFloat, "NAN", DBL2NUM(nan("")));
5678
5679 rb_define_method(rb_cFloat, "to_s", flo_to_s, 0);
5680 rb_define_alias(rb_cFloat, "inspect", "to_s");
5681 rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
5682 rb_define_method(rb_cFloat, "-@", rb_float_uminus, 0);
5683 rb_define_method(rb_cFloat, "+", rb_float_plus, 1);
5684 rb_define_method(rb_cFloat, "-", rb_float_minus, 1);
5685 rb_define_method(rb_cFloat, "*", rb_float_mul, 1);
5686 rb_define_method(rb_cFloat, "/", rb_float_div, 1);
5687 rb_define_method(rb_cFloat, "quo", flo_quo, 1);
5688 rb_define_method(rb_cFloat, "fdiv", flo_quo, 1);
5689 rb_define_method(rb_cFloat, "%", flo_mod, 1);
5690 rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
5691 rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
5692 rb_define_method(rb_cFloat, "**", rb_float_pow, 1);
5693 rb_define_method(rb_cFloat, "==", flo_eq, 1);
5694 rb_define_method(rb_cFloat, "===", flo_eq, 1);
5695 rb_define_method(rb_cFloat, "<=>", flo_cmp, 1);
5696 rb_define_method(rb_cFloat, ">", rb_float_gt, 1);
5697 rb_define_method(rb_cFloat, ">=", flo_ge, 1);
5698 rb_define_method(rb_cFloat, "<", flo_lt, 1);
5699 rb_define_method(rb_cFloat, "<=", flo_le, 1);
5700 rb_define_method(rb_cFloat, "eql?", flo_eql, 1);
5701 rb_define_method(rb_cFloat, "hash", flo_hash, 0);
5702 rb_define_method(rb_cFloat, "to_f", flo_to_f, 0);
5703 rb_define_method(rb_cFloat, "abs", rb_float_abs, 0);
5704 rb_define_method(rb_cFloat, "magnitude", rb_float_abs, 0);
5705 rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0);
5706
5707 rb_define_method(rb_cFloat, "to_i", flo_to_i, 0);
5708 rb_define_method(rb_cFloat, "to_int", flo_to_i, 0);
5709 rb_define_method(rb_cFloat, "floor", flo_floor, -1);
5710 rb_define_method(rb_cFloat, "ceil", flo_ceil, -1);
5711 rb_define_method(rb_cFloat, "round", flo_round, -1);
5712 rb_define_method(rb_cFloat, "truncate", flo_truncate, -1);
5713
5714 rb_define_method(rb_cFloat, "nan?", flo_is_nan_p, 0);
5715 rb_define_method(rb_cFloat, "infinite?", rb_flo_is_infinite_p, 0);
5716 rb_define_method(rb_cFloat, "finite?", rb_flo_is_finite_p, 0);
5717 rb_define_method(rb_cFloat, "next_float", flo_next_float, 0);
5718 rb_define_method(rb_cFloat, "prev_float", flo_prev_float, 0);
5719 rb_define_method(rb_cFloat, "positive?", flo_positive_p, 0);
5720 rb_define_method(rb_cFloat, "negative?", flo_negative_p, 0);
5721}
5722
5723#undef rb_float_value
5724double
5725 rb_float_value(VALUE v)
5726{
5727 return rb_float_value_inline(v);
5728}
5729
5730#undef rb_float_new
5731 VALUE
5732 rb_float_new(double d)
5733{
5734 return rb_float_new_inline(d);
5735}
5736
5737#include "integer.rbinc"
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1301
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:749
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:975
assert.h
NORETURN
#define NORETURN(x)
Definition: attributes.h:152
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN
Definition: assume.h:31
BDIGIT_DBL
#define BDIGIT_DBL
Definition: bigdecimal.h:49
BDIGIT
#define BDIGIT
Definition: bigdecimal.h:48
rb_big_lshift
VALUE rb_big_lshift(VALUE x, VALUE y)
Definition: bignum.c:6618
rb_big_even_p
VALUE rb_big_even_p(VALUE num)
Definition: bignum.c:6837
rb_big_and
VALUE rb_big_and(VALUE x, VALUE y)
Definition: bignum.c:6357
rb_big_or
VALUE rb_big_or(VALUE x, VALUE y)
Definition: bignum.c:6476
rb_big_size
size_t rb_big_size(VALUE big)
Definition: bignum.c:6775
rb_big_minus
VALUE rb_big_minus(VALUE x, VALUE y)
Definition: bignum.c:5850
rb_big_modulo
VALUE rb_big_modulo(VALUE x, VALUE y)
Definition: bignum.c:6100
rb_big_fdiv_double
double rb_big_fdiv_double(VALUE x, VALUE y)
Definition: bignum.c:6206
rb_big_pow
VALUE rb_big_pow(VALUE x, VALUE y)
Definition: bignum.c:6241
rb_int2big
VALUE rb_int2big(intptr_t n)
Definition: bignum.c:3186
rb_bigzero_p
int rb_bigzero_p(VALUE x)
Definition: bignum.c:2924
rb_big_comp
VALUE rb_big_comp(VALUE x)
Definition: bignum.c:5561
rb_big_plus
VALUE rb_big_plus(VALUE x, VALUE y)
Definition: bignum.c:5821
rb_absint_size
size_t rb_absint_size(VALUE val, int *nlz_bits_ret)
Definition: bignum.c:3253
rb_big2ulong
unsigned long rb_big2ulong(VALUE x)
Definition: bignum.c:5124
rb_big_idiv
VALUE rb_big_idiv(VALUE x, VALUE y)
Definition: bignum.c:6094
rb_big_gt
VALUE rb_big_gt(VALUE x, VALUE y)
Definition: bignum.c:5486
rb_big_ge
VALUE rb_big_ge(VALUE x, VALUE y)
Definition: bignum.c:5492
rb_big2str
VALUE rb_big2str(VALUE x, int base)
Definition: bignum.c:5090
rb_big_aref
VALUE rb_big_aref(VALUE x, VALUE y)
Definition: bignum.c:6678
rb_integer_float_eq
COMPILER_WARNING_POP VALUE rb_integer_float_eq(VALUE x, VALUE y)
Definition: bignum.c:5383
rb_big_bit_length
VALUE rb_big_bit_length(VALUE big)
Definition: bignum.c:6787
rb_big_cmp
VALUE rb_big_cmp(VALUE x, VALUE y)
Definition: bignum.c:5416
rb_dbl2big
VALUE rb_dbl2big(double d)
Definition: bignum.c:5248
rb_big_eq
VALUE rb_big_eq(VALUE x, VALUE y)
Definition: bignum.c:5521
rb_big_eql
VALUE rb_big_eql(VALUE x, VALUE y)
Definition: bignum.c:5541
rb_big_mul
VALUE rb_big_mul(VALUE x, VALUE y)
Definition: bignum.c:5930
rb_big_lt
VALUE rb_big_lt(VALUE x, VALUE y)
Definition: bignum.c:5498
rb_big_remainder
VALUE rb_big_remainder(VALUE x, VALUE y)
Definition: bignum.c:6116
rb_big_odd_p
VALUE rb_big_odd_p(VALUE num)
Definition: bignum.c:6828
rb_big_size_m
VALUE rb_big_size_m(VALUE big)
Definition: bignum.c:6781
ruby_digitmap
const char ruby_digitmap[]
Definition: bignum.c:48
rb_int_powm
VALUE rb_int_powm(int const argc, VALUE *const argv, VALUE const num)
Definition: bignum.c:7108
rb_integer_float_cmp
VALUE rb_integer_float_cmp(VALUE x, VALUE y)
Definition: bignum.c:5324
rb_big_divmod
VALUE rb_big_divmod(VALUE x, VALUE y)
Definition: bignum.c:6132
rb_big_xor
VALUE rb_big_xor(VALUE x, VALUE y)
Definition: bignum.c:6570
rb_big_div
VALUE rb_big_div(VALUE x, VALUE y)
Definition: bignum.c:6088
rb_big_norm
VALUE rb_big_norm(VALUE x)
Definition: bignum.c:3158
rb_big_uminus
VALUE rb_big_uminus(VALUE x)
Definition: bignum.c:5551
rb_big_rshift
VALUE rb_big_rshift(VALUE x, VALUE y)
Definition: bignum.c:6648
rb_big2dbl
double rb_big2dbl(VALUE x)
Definition: bignum.c:5309
rb_big_abs
VALUE rb_big_abs(VALUE x)
Definition: bignum.c:6759
rb_big2long
long rb_big2long(VALUE x)
Definition: bignum.c:5139
rb_ulong_isqrt
unsigned long rb_ulong_isqrt(unsigned long)
rb_big_le
VALUE rb_big_le(VALUE x, VALUE y)
Definition: bignum.c:5504
bit_length
#define bit_length(x)
Definition: bits.h:140
MUL_OVERFLOW_FIXNUM_P
#define MUL_OVERFLOW_FIXNUM_P(a, b)
Definition: bits.h:113
decode
int decode(struct state *s, struct huffman *h)
Definition: blast.c:129
rb_mComparable
VALUE rb_mComparable
Definition: compar.c:19
rb_cmperr
void rb_cmperr(VALUE x, VALUE y)
Definition: compar.c:28
compilers.h
Internal header absorbing C compipler differences.
rb_complex_plus
VALUE rb_complex_plus(VALUE self, VALUE other)
Definition: complex.c:787
rb_complex_pow
VALUE rb_complex_pow(VALUE self, VALUE other)
Definition: complex.c:994
rb_dbl_complex_new_polar_pi
VALUE rb_dbl_complex_new_polar_pi(double abs, double ang)
Definition: complex.c:669
rb_complex_new
VALUE rb_complex_new(VALUE x, VALUE y)
Definition: complex.c:1542
rb_complex_mul
VALUE rb_complex_mul(VALUE self, VALUE other)
Definition: complex.c:881
ctype.h
Our own, locale independent, character handling routines.
ISALNUM
#define ISALNUM
Definition: ctype.h:41
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
mod
#define mod(x, y)
Definition: date_strftime.c:28
div
#define div(x, y)
Definition: date_strftime.c:27
mask
enum @11::@13::@14 mask
ptr
struct RIMemo * ptr
Definition: debug.c:88
strchr
char * strchr(char *, char)
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: dllexport.h:55
assert
#define assert(x)
Definition: dlmalloc.c:1176
RFLOAT_VALUE
#define RFLOAT_VALUE
Definition: double.h:28
NUM2DBL
#define NUM2DBL
Definition: double.h:27
DBL2NUM
#define DBL2NUM
Definition: double.h:29
rb_enc_precise_mbclen
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:1230
rb_ascii8bit_encoding
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1525
rb_default_internal_encoding
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1734
rb_to_encoding
rb_encoding * rb_to_encoding(VALUE enc)
Definition: encoding.c:329
rb_enc_codelen
int rb_enc_codelen(int c, rb_encoding *enc)
Definition: encoding.c:1287
num
big_t * num
Definition: enough.c:232
rb_cmpint
#define rb_cmpint(cmp, a, b)
rb_arith_seq_new
VALUE rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv, rb_enumerator_size_func *size_fn, VALUE beg, VALUE end, VALUE step, int excl)
Definition: enumerator.c:3327
len
uint8_t len
Definition: escape.c:17
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
rb_deprecate_constant
#define rb_deprecate_constant(mod, name)
Definition: etc.c:60
RSTRING_LEN
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
memcpy
#define memcpy(d, s, n)
Definition: ffi_common.h:55
LIKELY
#define LIKELY(x)
Definition: ffi_common.h:125
FL_WB_PROTECTED
#define FL_WB_PROTECTED
Definition: fl_type.h:50
PRIsVALUE
#define PRIsVALUE
Definition: function.c:10
CLASS_OF
#define CLASS_OF
Definition: globals.h:153
rb_eMathDomainError
VALUE rb_eMathDomainError
Definition: math.c:37
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:962
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:748
rb_singleton_class
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1924
rb_frame_this_func
ID rb_frame_this_func(void)
The original name of the current method.
Definition: eval.c:1216
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1777
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1999
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:935
rb_get_kwargs
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:2085
OBJ_FREEZE
#define OBJ_FREEZE
Definition: fl_type.h:134
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_eNotImpError
VALUE rb_eNotImpError
Definition: error.c:1067
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:768
rb_name_error
void rb_name_error(ID id, const char *fmt,...)
Definition: error.c:1649
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:1054
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:1061
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:1057
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1058
rb_Float
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
Definition: object.c:3531
rb_cObject
VALUE rb_cObject
Object class.
Definition: object.c:49
rb_any_to_s
VALUE rb_any_to_s(VALUE)
Default implementation of #to_s.
Definition: object.c:561
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:245
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:585
rb_equal
VALUE rb_equal(VALUE, VALUE)
This function is an optimized version of calling #==.
Definition: object.c:157
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:724
rb_immutable_obj_clone
VALUE rb_immutable_obj_clone(int, VALUE *, VALUE)
Definition: object.c:360
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3051
gcd
unsigned gcd(unsigned a, unsigned b)
Definition: gzappend.c:102
rb_dbl_long_hash
long rb_dbl_long_hash(double d)
Definition: hash.c:180
id.h
idGE
@ idGE
Definition: id.h:95
idUMinus
@ idUMinus
Definition: id.h:82
idLE
@ idLE
Definition: id.h:93
idPow
@ idPow
Definition: id.h:83
encoding.h
rb_enc_mbcput
#define rb_enc_mbcput(c, buf, enc)
Definition: encoding.h:208
rb_enc_str_new
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:857
rb_enc_name
#define rb_enc_name(enc)
Definition: encoding.h:168
FIXABLE
#define FIXABLE
Definition: fixnum.h:25
POSFIXABLE
#define POSFIXABLE
Definition: fixnum.h:29
config.h
Thin wrapper to ruby/config.h.
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
builtin.h
Defines RBIMPL_HAS_BUILTIN.
SIZED_ENUMERATOR
#define SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: enumerator.h:56
RETURN_SIZED_ENUMERATOR
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: enumerator.h:64
rb_error_arity
void rb_error_arity(int, int, int)
Definition: vm_insnhelper.c:442
rb_check_arity
#define rb_check_arity
Definition: error.h:34
rb_range_values
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Definition: range.c:1310
rb_rational_raw
VALUE rb_rational_raw(VALUE, VALUE)
Definition: rational.c:1948
rb_memcicmp
int rb_memcicmp(const void *, const void *, long)
Definition: re.c:88
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2859
rb_must_asciicompat
void rb_must_asciicompat(VALUE)
Definition: string.c:2314
rb_str_new
#define rb_str_new(str, len)
Definition: string.h:213
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2962
rb_usascii_str_new
#define rb_usascii_str_new(str, len)
Definition: string.h:224
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2462
rb_usascii_str_new_cstr
#define rb_usascii_str_new_cstr(str)
Definition: string.h:241
rb_usascii_str_new2
#define rb_usascii_str_new2
Definition: string.h:282
rb_exec_recursive_paired
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:5371
rb_exec_recursive
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5360
rb_remove_method_id
void rb_remove_method_id(VALUE, ID)
Definition: vm_method.c:1351
rb_check_funcall
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:619
rb_undef_alloc_func
void rb_undef_alloc_func(VALUE)
Definition: vm_method.c:954
ID2SYM
#define ID2SYM
Definition: symbol.h:44
rb_id2name
const char * rb_id2name(ID)
Definition: symbol.c:944
rb_sym2str
VALUE rb_sym2str(VALUE)
Definition: symbol.c:927
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:785
rb_to_id
ID rb_to_id(VALUE)
Definition: string.c:11501
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:3150
isfinite
#define isfinite(x)
Definition: missing.h:187
signbit
int signbit(double x)
Definition: signbit.c:5
nan
double nan(const char *)
Definition: nan.c:7
memmove
void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
nextafter
double nextafter(double x, double y)
Definition: nextafter.c:9
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:156
util.h
FIX2INT
#define FIX2INT
Definition: int.h:41
NUM2INT
#define NUM2INT
Definition: int.h:44
NUM2LL
#define NUM2LL
Definition: long_long.h:34
rb_num2ull
unsigned LONG_LONG rb_num2ull(VALUE)
NUM2ULL
#define NUM2ULL
Definition: long_long.h:35
rb_num2ll
LONG_LONG rb_num2ll(VALUE)
array.h
Internal header for Array.
complex.h
Internal header for Complex.
enumerator.h
Internal header for Enumerator.
hash.h
Internal header for Hash.
numeric.h
Internal header for Numeric.
rb_float_value
#define rb_float_value
Definition: numeric.h:94
rb_float_new
#define rb_float_new
Definition: numeric.h:95
ruby_num_rounding_mode
ruby_num_rounding_mode
Definition: numeric.h:32
RUBY_NUM_ROUND_HALF_EVEN
@ RUBY_NUM_ROUND_HALF_EVEN
Definition: numeric.h:34
RUBY_NUM_ROUND_HALF_DOWN
@ RUBY_NUM_ROUND_HALF_DOWN
Definition: numeric.h:35
RUBY_NUM_ROUND_HALF_UP
@ RUBY_NUM_ROUND_HALF_UP
Definition: numeric.h:33
RUBY_NUM_ROUND_DEFAULT
@ RUBY_NUM_ROUND_DEFAULT
Definition: numeric.h:36
ROUND_CALL
#define ROUND_CALL(mode, name, args)
Definition: numeric.h:24
object.h
Internal header for Object.
rational.h
Internal header for Rational.
rb_rational_pow
VALUE rb_rational_pow(VALUE self, VALUE other)
Definition: rational.c:976
rb_rational_reciprocal
VALUE rb_rational_reciprocal(VALUE x)
Definition: rational.c:1884
rb_gcd
VALUE rb_gcd(VALUE x, VALUE y)
Definition: rational.c:1903
util.h
Internal header corresponding util.c.
ruby_dtoa
char * ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
rb_yield_1
VALUE rb_yield_1(VALUE val)
Definition: vm_eval.c:1335
internal.h
rb_ary_new_from_args
#define rb_ary_new_from_args(...)
Definition: internal.h:65
rb_funcallv
#define rb_funcallv(...)
Definition: internal.h:77
PRIdVALUE
#define PRIdVALUE
Definition: inttypes.h:72
long
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
int
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
mode
const char int mode
Definition: ioapi.h:137
buf
voidpf void * buf
Definition: ioapi.h:138
isinf
int isinf(double n)
Definition: isinf.c:56
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1341
CHAR_BIT
#define CHAR_BIT
Definition: limits.h:44
INT2FIX
#define INT2FIX
Definition: long.h:48
RB_FIX2ULONG
#define RB_FIX2ULONG
Definition: long.h:54
ULONG2NUM
#define ULONG2NUM
Definition: long.h:60
LONG2FIX
#define LONG2FIX
Definition: long.h:49
FIX2ULONG
#define FIX2ULONG
Definition: long.h:47
LONG2NUM
#define LONG2NUM
Definition: long.h:50
FIX2LONG
#define FIX2LONG
Definition: long.h:46
NUM2LONG
#define NUM2LONG
Definition: long.h:51
math.h
Internal header for Math.
NEWOBJ_OF
#define NEWOBJ_OF
Definition: newobj.h:35
name
const char * name
Definition: nkf.c:208
TRUE
#define TRUE
Definition: nkf.h:175
FALSE
#define FALSE
Definition: nkf.h:174
rb_int_negative_p
int rb_int_negative_p(VALUE num)
Definition: numeric.c:313
rb_num_zerodiv
void rb_num_zerodiv(void)
Definition: numeric.c:199
rb_float_uminus
VALUE rb_float_uminus(VALUE flt)
Definition: numeric.c:1041
id_to_i
#define id_to_i
Definition: numeric.c:185
rb_infinity
const union bytesequence4_or_float rb_infinity
Definition: numeric.c:78
DBL_MIN_EXP
#define DBL_MIN_EXP
Definition: numeric.c:55
rb_float_floor
VALUE rb_float_floor(VALUE num, int ndigits)
Definition: numeric.c:1935
FIT_SQRT_LONG
#define FIT_SQRT_LONG(n)
Definition: numeric.c:3650
NUMERR_TYPE
#define NUMERR_TYPE
id_divmod
#define id_divmod
Definition: numeric.c:184
rb_int_modulo
VALUE rb_int_modulo(VALUE x, VALUE y)
Definition: numeric.c:3873
rb_fix_aref
VALUE rb_fix_aref(VALUE fix, VALUE idx)
Definition: numeric.c:4613
FLOAT_OUT_OF_RANGE
#define FLOAT_OUT_OF_RANGE(val, type)
Definition: numeric.c:2879
rb_num_pow
VALUE rb_num_pow(VALUE x, VALUE y)
Definition: numeric.c:4100
NUMERR_NEGATIVE
#define NUMERR_NEGATIVE
rb_int_comp
VALUE rb_int_comp(VALUE num)
Definition: numeric.c:4372
rb_int_truncate
VALUE rb_int_truncate(VALUE num, int ndigits)
Definition: numeric.c:2226
rb_num2fix
VALUE rb_num2fix(VALUE val)
Definition: numeric.c:3140
NUMERR_TOOLARGE
#define NUMERR_TOOLARGE
rb_int_abs
VALUE rb_int_abs(VALUE num)
Definition: numeric.c:4826
rb_int_div
VALUE rb_int_div(VALUE x, VALUE y)
Definition: numeric.c:3803
method_basic_p
#define method_basic_p(klass)
Definition: numeric.c:280
rb_eZeroDivError
VALUE rb_eZeroDivError
Definition: numeric.c:193
rb_int_zero_p
VALUE rb_int_zero_p(VALUE num)
Definition: numeric.c:800
rb_fix2short
short rb_fix2short(VALUE val)
Definition: numeric.c:3107
rb_float_pow
VALUE rb_float_pow(VALUE x, VALUE y)
Definition: numeric.c:1328
rb_int_pow
VALUE rb_int_pow(VALUE x, VALUE y)
Definition: numeric.c:4088
rb_num2long
long rb_num2long(VALUE val)
Definition: numeric.c:2894
rb_cInteger
VALUE rb_cInteger
Definition: numeric.c:191
DBL_MAX_EXP
#define DBL_MAX_EXP
Definition: numeric.c:58
rb_float_equal
VALUE rb_float_equal(VALUE x, VALUE y)
Definition: numeric.c:1417
FLT_RADIX
#define FLT_RADIX
Definition: numeric.c:46
DBL_MIN_10_EXP
#define DBL_MIN_10_EXP
Definition: numeric.c:61
rb_enc_uint_chr
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
Definition: numeric.c:3391
rb_int_uminus
VALUE rb_int_uminus(VALUE num)
Definition: numeric.c:3466
rb_float_mul
VALUE rb_float_mul(VALUE x, VALUE y)
Definition: numeric.c:1102
rb_int_equal
VALUE rb_int_equal(VALUE x, VALUE y)
Definition: numeric.c:4147
rb_float_plus
VALUE rb_float_plus(VALUE x, VALUE y)
Definition: numeric.c:1054
rb_int_positive_pow
VALUE rb_int_positive_pow(long x, unsigned long y)
Definition: numeric.c:4022
rb_flo_div_flo
VALUE rb_flo_div_flo(VALUE x, VALUE y)
Definition: numeric.c:1140
rb_num_coerce_cmp
VALUE rb_num_coerce_cmp(VALUE x, VALUE y, ID func)
Definition: numeric.c:459
rb_int_cmp
VALUE rb_int_cmp(VALUE x, VALUE y)
Definition: numeric.c:4196
ULONG_MAX_PLUS_ONE
#define ULONG_MAX_PLUS_ONE
Definition: numeric.c:2887
DBL_MAX_10_EXP
#define DBL_MAX_10_EXP
Definition: numeric.c:64
rb_int2str
VALUE rb_int2str(VALUE x, int base)
Definition: numeric.c:3549
ruby_float_mod
double ruby_float_mod(double x, double y)
Definition: numeric.c:1237
rb_float_eql
VALUE rb_float_eql(VALUE x, VALUE y)
Definition: numeric.c:1688
rb_fix2uint
unsigned long rb_fix2uint(VALUE val)
Definition: numeric.c:3060
domain_error
#define domain_error(msg)
Definition: numeric.c:5324
rb_int_and
VALUE rb_int_and(VALUE x, VALUE y)
Definition: numeric.c:4436
round
double round(double x)
Definition: numeric.c:92
rb_float_abs
VALUE rb_float_abs(VALUE flt)
Definition: numeric.c:1732
rb_int_even_p
VALUE rb_int_even_p(VALUE num)
Definition: numeric.c:3273
rb_num_coerce_bin
VALUE rb_num_coerce_bin(VALUE x, VALUE y, ID func)
Definition: numeric.c:452
rb_cNumeric
VALUE rb_cNumeric
Definition: numeric.c:189
DEFINE_INT_SQRT
#define DEFINE_INT_SQRT(rettype, prefix, argtype)
Definition: numeric.c:5286
rb_int_lshift
VALUE rb_int_lshift(VALUE x, VALUE y)
Definition: numeric.c:4553
ruby_float_step_size
double ruby_float_step_size(double beg, double end, double unit, int excl)
Definition: numeric.c:2537
int_succ
#define int_succ
Definition: numeric.c:3349
id_eq
#define id_eq
Definition: numeric.c:186
rb_num2short
short rb_num2short(VALUE val)
Definition: numeric.c:3098
flo_eql
#define flo_eql
Definition: numeric.c:1702
rb_float_gt
VALUE rb_float_gt(VALUE x, VALUE y)
Definition: numeric.c:1537
num_clone
#define num_clone
Definition: numeric.c:522
rb_int_fdiv
VALUE rb_int_fdiv(VALUE x, VALUE y)
Definition: numeric.c:3748
rb_float_ceil
VALUE rb_float_ceil(VALUE num, int ndigits)
Definition: numeric.c:2059
rb_int_fdiv_double
double rb_int_fdiv_double(VALUE x, VALUE y)
Definition: numeric.c:3715
rb_int_positive_p
int rb_int_positive_p(VALUE num)
Definition: numeric.c:307
rb_eFloatDomainError
VALUE rb_eFloatDomainError
Definition: numeric.c:194
rb_out_of_int
void rb_out_of_int(SIGNED_VALUE num)
Definition: numeric.c:2969
ruby_num_interval_step_size
VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
Definition: numeric.c:2597
rb_num2uint
unsigned long rb_num2uint(VALUE val)
Definition: numeric.c:3054
Init_Numeric
void Init_Numeric(void)
Definition: numeric.c:5483
ruby_float_step
int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless)
Definition: numeric.c:2566
rb_num_get_rounding_option
enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts)
Definition: numeric.c:205
rb_flo_is_finite_p
VALUE rb_flo_is_finite_p(VALUE num)
Definition: numeric.c:1804
rb_nan
const union bytesequence4_or_float rb_nan
Definition: numeric.c:85
id_div
#define id_div
Definition: numeric.c:183
DBL_DIG
#define DBL_DIG
Definition: numeric.c:67
rb_num_coerce_bit
VALUE rb_num_coerce_bit(VALUE x, VALUE y, ID func)
Definition: numeric.c:4395
rb_int_ge
VALUE rb_int_ge(VALUE x, VALUE y)
Definition: numeric.c:4276
DBL_MIN
#define DBL_MIN
Definition: numeric.c:49
DBL_EPSILON
#define DBL_EPSILON
Definition: numeric.c:73
rb_float_div
VALUE rb_float_div(VALUE x, VALUE y)
Definition: numeric.c:1156
rb_fix2str
VALUE rb_fix2str(VALUE x, int base)
Definition: numeric.c:3495
RB_ULONG
#define RB_ULONG
Definition: numeric.c:5307
LONG_MIN_MINUS_ONE_IS_LESS_THAN
#define LONG_MIN_MINUS_ONE_IS_LESS_THAN(n)
Definition: numeric.c:2888
rb_int_minus
VALUE rb_int_minus(VALUE x, VALUE y)
Definition: numeric.c:3636
rb_flo_is_infinite_p
VALUE rb_flo_is_infinite_p(VALUE num)
Definition: numeric.c:1784
rb_int_odd_p
VALUE rb_int_odd_p(VALUE num)
Definition: numeric.c:3243
rb_num2int
long rb_num2int(VALUE val)
Definition: numeric.c:3042
rb_num_to_uint
int rb_num_to_uint(VALUE val, unsigned int *ret)
Definition: numeric.c:250
rb_fix_plus
VALUE rb_fix_plus(VALUE x, VALUE y)
Definition: numeric.c:3591
rb_fix2ushort
unsigned short rb_fix2ushort(VALUE val)
Definition: numeric.c:3126
rb_num2ulong
unsigned long rb_num2ulong(VALUE val)
Definition: numeric.c:2963
rb_int_divmod
VALUE rb_int_divmod(VALUE x, VALUE y)
Definition: numeric.c:3950
int_pred
#define int_pred
Definition: numeric.c:3375
rb_float_cmp
int rb_float_cmp(VALUE x, VALUE y)
Definition: numeric.c:1521
rb_float_new_in_heap
VALUE rb_float_new_in_heap(double d)
Definition: numeric.c:922
rb_int_bit_length
VALUE rb_int_bit_length(VALUE num)
Definition: numeric.c:4881
rb_int_idiv
VALUE rb_int_idiv(VALUE x, VALUE y)
Definition: numeric.c:3830
rb_big_isqrt
VALUE rb_big_isqrt(VALUE)
Definition: bignum.c:6908
rb_num_negative_p
int rb_num_negative_p(VALUE num)
Definition: numeric.c:319
rb_cFloat
VALUE rb_cFloat
Definition: numeric.c:190
rb_dbl_cmp
VALUE rb_dbl_cmp(double a, double b)
Definition: numeric.c:1465
rb_float_minus
VALUE rb_float_minus(VALUE x, VALUE y)
Definition: numeric.c:1078
DBL_MANT_DIG
#define DBL_MANT_DIG
Definition: numeric.c:70
rb_num2ushort
unsigned short rb_num2ushort(VALUE val)
Definition: numeric.c:3116
rb_num_coerce_relop
VALUE rb_num_coerce_relop(VALUE x, VALUE y, ID func)
Definition: numeric.c:474
num_dup
#define num_dup
Definition: numeric.c:538
flo_eq
#define flo_eq
Definition: numeric.c:1440
LONG_MAX_PLUS_ONE
#define LONG_MAX_PLUS_ONE
Definition: numeric.c:2886
rb_fix2int
long rb_fix2int(VALUE val)
Definition: numeric.c:3048
id_cmp
#define id_cmp
Definition: numeric.c:187
rb_int_plus
VALUE rb_int_plus(VALUE x, VALUE y)
Definition: numeric.c:3597
DBL_MAX
#define DBL_MAX
Definition: numeric.c:52
rb_int_gt
VALUE rb_int_gt(VALUE x, VALUE y)
Definition: numeric.c:4236
rb_int_succ
VALUE rb_int_succ(VALUE num)
Definition: numeric.c:3337
rb_int_mul
VALUE rb_int_mul(VALUE x, VALUE y)
Definition: numeric.c:3686
ONIGERR_TOO_BIG_WIDE_CHAR_VALUE
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE
Definition: onigmo.h:691
ONIGERR_INVALID_CODE_POINT_VALUE
#define ONIGERR_INVALID_CODE_POINT_VALUE
Definition: onigmo.h:689
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(s)
Definition: psych_emitter.c:4
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
RARRAY_LEN
#define RARRAY_LEN
Definition: rarray.h:52
NULL
#define NULL
Definition: regenc.h:69
RGENGC_WB_PROTECTED_FLOAT
#define RGENGC_WB_PROTECTED_FLOAT
Definition: rgengc.h:76
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:308
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
RB_INTEGER_TYPE_P
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
Qundef
#define Qundef
Definition: special_consts.h:53
SPECIAL_CONST_P
#define SPECIAL_CONST_P
Definition: special_consts.h:47
Qtrue
#define Qtrue
Definition: special_consts.h:52
RTEST
#define RTEST
Definition: special_consts.h:42
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
NIL_P
#define NIL_P
Definition: special_consts.h:46
FIXNUM_P
#define FIXNUM_P
Definition: special_consts.h:44
f
#define f
rb_str_catf
VALUE rb_str_catf(VALUE, const char *,...)
Definition: sprintf.c:1243
strlen
size_t strlen(const char *)
OnigEncodingTypeST
Definition: onigmo.h:160
RFloat
Definition: numeric.h:39
code
Definition: inftree9.h:24
snprintf
#define snprintf
Definition: subst.h:14
neg
#define neg(x)
Definition: time.c:151
bytesequence4_or_float
Definition: missing.h:135
VALUE
unsigned long VALUE
Definition: value.h:38
SIGNED_VALUE
#define SIGNED_VALUE
Definition: value.h:40
SIZEOF_VALUE
#define SIZEOF_VALUE
Definition: value.h:41
ID
unsigned long ID
Definition: value.h:39
T_COMPLEX
#define T_COMPLEX
Definition: value_type.h:58
TYPE
#define TYPE(_)
Definition: value_type.h:105
T_STRING
#define T_STRING
Definition: value_type.h:77
T_NIL
#define T_NIL
Definition: value_type.h:71
T_FLOAT
#define T_FLOAT
Definition: value_type.h:63
T_BIGNUM
#define T_BIGNUM
Definition: value_type.h:56
T_FIXNUM
#define T_FIXNUM
Definition: value_type.h:62
T_TRUE
#define T_TRUE
Definition: value_type.h:80
T_RATIONAL
#define T_RATIONAL
Definition: value_type.h:75
T_FALSE
#define T_FALSE
Definition: value_type.h:60
T_ARRAY
#define T_ARRAY
Definition: value_type.h:55
BUILTIN_TYPE
#define BUILTIN_TYPE
Definition: value_type.h:84
SYMBOL_P
#define SYMBOL_P
Definition: value_type.h:87
rb_id2str
#define rb_id2str(id)
Definition: vm_backtrace.c:30
err
int err
Definition: win32.c:142
isnan
#define isnan(x)
Definition: win32.h:346
strncasecmp
#define strncasecmp
Definition: win32.h:208
xfree
#define xfree
Definition: xmalloc.h:49
inf
int inf(FILE *source, FILE *dest)
Definition: zpipe.c:92