Ruby: internal/numeric.h Source File

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

numeric.h
Go to the documentation of this file.
1#ifndef INTERNAL_NUMERIC_H /*-*-C-*-vi:se ft=c:*/
2#define INTERNAL_NUMERIC_H
12#include "internal/bignum.h" /* for BIGNUM_POSITIVE_P */
13#include "internal/bits.h" /* for RUBY_BIT_ROTL */
14#include "internal/fixnum.h" /* for FIXNUM_POSITIVE_P */
15#include "internal/vm.h" /* for rb_method_basic_definition_p */
16#include "ruby/intern.h" /* for rb_cmperr */
17#include "ruby/ruby.h" /* for USE_FLONUM */
18
19#define ROUND_TO(mode, even, up, down) \
20 ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \
21 (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
22#define ROUND_FUNC(mode, name) \
23 ROUND_TO(mode, name##_half_even, name##_half_up, name##_half_down)
24#define ROUND_CALL(mode, name, args) \
25 ROUND_TO(mode, name##_half_even args, \
26 name##_half_up args, name##_half_down args)
27
28#ifndef ROUND_DEFAULT
29# define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
30#endif
31
32 enum ruby_num_rounding_mode {
33 RUBY_NUM_ROUND_HALF_UP,
34 RUBY_NUM_ROUND_HALF_EVEN,
35 RUBY_NUM_ROUND_HALF_DOWN,
36 RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT,
37};
38
39 struct RFloat {
40 struct RBasic basic;
41 double float_value;
42};
43
44#define RFLOAT(obj) ((struct RFloat *)(obj))
45
46/* numeric.c */
47int rb_num_to_uint(VALUE val, unsigned int *ret);
48 VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl);
49double ruby_float_step_size(double beg, double end, double unit, int excl);
50int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless);
51int rb_num_negative_p(VALUE);
52 VALUE rb_int_succ(VALUE num);
53 VALUE rb_float_uminus(VALUE num);
54 VALUE rb_int_plus(VALUE x, VALUE y);
55 VALUE rb_float_plus(VALUE x, VALUE y);
56 VALUE rb_int_minus(VALUE x, VALUE y);
57 VALUE rb_float_minus(VALUE x, VALUE y);
58 VALUE rb_int_mul(VALUE x, VALUE y);
59 VALUE rb_float_mul(VALUE x, VALUE y);
60 VALUE rb_float_div(VALUE x, VALUE y);
61 VALUE rb_int_idiv(VALUE x, VALUE y);
62 VALUE rb_int_modulo(VALUE x, VALUE y);
63 VALUE rb_int2str(VALUE num, int base);
64 VALUE rb_fix_plus(VALUE x, VALUE y);
65 VALUE rb_int_gt(VALUE x, VALUE y);
66 VALUE rb_float_gt(VALUE x, VALUE y);
67 VALUE rb_int_ge(VALUE x, VALUE y);
68enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
69double rb_int_fdiv_double(VALUE x, VALUE y);
70 VALUE rb_int_pow(VALUE x, VALUE y);
71 VALUE rb_float_pow(VALUE x, VALUE y);
72 VALUE rb_int_cmp(VALUE x, VALUE y);
73 VALUE rb_int_equal(VALUE x, VALUE y);
74 VALUE rb_int_divmod(VALUE x, VALUE y);
75 VALUE rb_int_and(VALUE x, VALUE y);
76 VALUE rb_int_lshift(VALUE x, VALUE y);
77 VALUE rb_int_div(VALUE x, VALUE y);
78int rb_int_positive_p(VALUE num);
79int rb_int_negative_p(VALUE num);
80 VALUE rb_num_pow(VALUE x, VALUE y);
81 VALUE rb_float_ceil(VALUE num, int ndigits);
82 VALUE rb_float_floor(VALUE x, int ndigits);
83 VALUE rb_float_abs(VALUE flt);
84static inline VALUE rb_num_compare_with_zero(VALUE num, ID mid);
85static inline int rb_num_positive_int_p(VALUE num);
86static inline int rb_num_negative_int_p(VALUE num);
87static inline double rb_float_flonum_value(VALUE v);
88static inline double rb_float_noflonum_value(VALUE v);
89static inline double rb_float_value_inline(VALUE v);
90static inline VALUE rb_float_new_inline(double d);
91static inline bool INT_POSITIVE_P(VALUE num);
92static inline bool INT_NEGATIVE_P(VALUE num);
93static inline bool FLOAT_ZERO_P(VALUE num);
94#define rb_float_value rb_float_value_inline
95#define rb_float_new rb_float_new_inline
96
97RUBY_SYMBOL_EXPORT_BEGIN
98/* numeric.c (export) */
99 VALUE rb_int_positive_pow(long x, unsigned long y);
100RUBY_SYMBOL_EXPORT_END
101
102 MJIT_SYMBOL_EXPORT_BEGIN
103 VALUE rb_flo_div_flo(VALUE x, VALUE y);
104double ruby_float_mod(double x, double y);
105 VALUE rb_float_equal(VALUE x, VALUE y);
106int rb_float_cmp(VALUE x, VALUE y);
107 VALUE rb_float_eql(VALUE x, VALUE y);
108 VALUE rb_fix_aref(VALUE fix, VALUE idx);
109 VALUE rb_int_zero_p(VALUE num);
110 VALUE rb_int_even_p(VALUE num);
111 VALUE rb_int_odd_p(VALUE num);
112 VALUE rb_int_abs(VALUE num);
113 VALUE rb_int_bit_length(VALUE num);
114 VALUE rb_int_uminus(VALUE num);
115 VALUE rb_int_comp(VALUE num);
116 MJIT_SYMBOL_EXPORT_END
117
118static inline bool
119INT_POSITIVE_P(VALUE num)
120{
121 if (FIXNUM_P(num)) {
122 return FIXNUM_POSITIVE_P(num);
123 }
124 else {
125 return BIGNUM_POSITIVE_P(num);
126 }
127}
128
129static inline bool
130INT_NEGATIVE_P(VALUE num)
131{
132 if (FIXNUM_P(num)) {
133 return FIXNUM_NEGATIVE_P(num);
134 }
135 else {
136 return BIGNUM_NEGATIVE_P(num);
137 }
138}
139
140static inline bool
141FLOAT_ZERO_P(VALUE num)
142{
143 return RFLOAT_VALUE(num) == 0.0;
144}
145
146static inline VALUE
147rb_num_compare_with_zero(VALUE num, ID mid)
148{
149 VALUE zero = INT2FIX(0);
150 VALUE r = rb_check_funcall(num, mid, 1, &zero);
151 if (r == Qundef) {
152 rb_cmperr(num, zero);
153 }
154 return r;
155}
156
157static inline int
158rb_num_positive_int_p(VALUE num)
159{
160 const ID mid = '>';
161
162 if (FIXNUM_P(num)) {
163 if (rb_method_basic_definition_p(rb_cInteger, mid))
164 return FIXNUM_POSITIVE_P(num);
165 }
166 else if (RB_TYPE_P(num, T_BIGNUM)) {
167 if (rb_method_basic_definition_p(rb_cInteger, mid))
168 return BIGNUM_POSITIVE_P(num);
169 }
170 return RTEST(rb_num_compare_with_zero(num, mid));
171}
172
173static inline int
174rb_num_negative_int_p(VALUE num)
175{
176 const ID mid = '<';
177
178 if (FIXNUM_P(num)) {
179 if (rb_method_basic_definition_p(rb_cInteger, mid))
180 return FIXNUM_NEGATIVE_P(num);
181 }
182 else if (RB_TYPE_P(num, T_BIGNUM)) {
183 if (rb_method_basic_definition_p(rb_cInteger, mid))
184 return BIGNUM_NEGATIVE_P(num);
185 }
186 return RTEST(rb_num_compare_with_zero(num, mid));
187}
188
189static inline double
190rb_float_flonum_value(VALUE v)
191{
192#if USE_FLONUM
193 if (v != (VALUE)0x8000000000000002) { /* LIKELY */
194 union {
195 double d;
196 VALUE v;
197 } t;
198
199 VALUE b63 = (v >> 63);
200 /* e: xx1... -> 011... */
201 /* xx0... -> 100... */
202 /* ^b63 */
203 t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(VALUE)0x03), 3);
204 return t.d;
205 }
206#endif
207 return 0.0;
208}
209
210static inline double
211rb_float_noflonum_value(VALUE v)
212{
213 return RFLOAT(v)->float_value;
214}
215
216static inline double
217rb_float_value_inline(VALUE v)
218{
219 if (FLONUM_P(v)) {
220 return rb_float_flonum_value(v);
221 }
222 return rb_float_noflonum_value(v);
223}
224
225static inline VALUE
226rb_float_new_inline(double d)
227{
228#if USE_FLONUM
229 union {
230 double d;
231 VALUE v;
232 } t;
233 int bits;
234
235 t.d = d;
236 bits = (int)((VALUE)(t.v >> 60) & 0x7);
237 /* bits contains 3 bits of b62..b60. */
238 /* bits - 3 = */
239 /* b011 -> b000 */
240 /* b100 -> b001 */
241
242 if (t.v != 0x3000000000000000 /* 1.72723e-77 */ &&
243 !((bits-3) & ~0x01)) {
244 return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02;
245 }
246 else if (t.v == (VALUE)0) {
247 /* +0.0 */
248 return 0x8000000000000002;
249 }
250 /* out of range */
251#endif
252 return rb_float_new_in_heap(d);
253}
254
255#endif /* INTERNAL_NUMERIC_H */
bits.h
Internal header for bitwise integer algorithms.
bits
int bits(struct state *s, int need)
Definition: blast.c:72
rb_cmperr
void rb_cmperr(VALUE x, VALUE y)
Definition: compar.c:28
MJIT_SYMBOL_EXPORT_END
#define MJIT_SYMBOL_EXPORT_END
Definition: dllexport.h:63
MJIT_SYMBOL_EXPORT_BEGIN
#define MJIT_SYMBOL_EXPORT_BEGIN
Definition: dllexport.h:62
RFLOAT_VALUE
#define RFLOAT_VALUE
Definition: double.h:28
rb_float_new_in_heap
VALUE rb_float_new_in_heap(double)
Definition: numeric.c:922
num
big_t * num
Definition: enough.c:232
rb_cInteger
VALUE rb_cInteger
Definition: numeric.c:191
rb_check_funcall
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:619
intern.h
bignum.h
Internal header for Bignums.
fixnum.h
Internal header for Fixnums.
rb_int_negative_p
int rb_int_negative_p(VALUE num)
Definition: numeric.c:313
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
rb_num_pow
VALUE rb_num_pow(VALUE x, VALUE y)
Definition: numeric.c:4100
rb_int_comp
VALUE rb_int_comp(VALUE num)
Definition: numeric.c:4372
rb_int_abs
VALUE rb_int_abs(VALUE num)
Definition: numeric.c:4826
rb_float_floor
VALUE rb_float_floor(VALUE x, int ndigits)
Definition: numeric.c:1935
rb_int_div
VALUE rb_int_div(VALUE x, VALUE y)
Definition: numeric.c:3803
rb_int_zero_p
VALUE rb_int_zero_p(VALUE num)
Definition: numeric.c:800
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_int2str
VALUE rb_int2str(VALUE num, int base)
Definition: numeric.c:3549
rb_float_equal
VALUE rb_float_equal(VALUE x, VALUE y)
Definition: numeric.c:1417
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_int_cmp
VALUE rb_int_cmp(VALUE x, VALUE y)
Definition: numeric.c:4196
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_int_and
VALUE rb_int_and(VALUE x, VALUE y)
Definition: numeric.c:4436
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_float_uminus
VALUE rb_float_uminus(VALUE num)
Definition: numeric.c:1041
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
rb_float_gt
VALUE rb_float_gt(VALUE x, VALUE y)
Definition: numeric.c:1537
rb_num_negative_p
int rb_num_negative_p(VALUE)
Definition: numeric.c:319
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
ruby_num_interval_step_size
VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
Definition: numeric.c:2597
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_int_ge
VALUE rb_int_ge(VALUE x, VALUE y)
Definition: numeric.c:4276
rb_float_div
VALUE rb_float_div(VALUE x, VALUE y)
Definition: numeric.c:1156
rb_int_minus
VALUE rb_int_minus(VALUE x, VALUE y)
Definition: numeric.c:3636
rb_int_odd_p
VALUE rb_int_odd_p(VALUE num)
Definition: numeric.c:3243
rb_num_to_uint
int rb_num_to_uint(VALUE val, unsigned int *ret)
Definition: numeric.c:250
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
rb_fix_plus
VALUE rb_fix_plus(VALUE x, VALUE y)
Definition: numeric.c:3591
rb_int_divmod
VALUE rb_int_divmod(VALUE x, VALUE y)
Definition: numeric.c:3950
rb_float_cmp
int rb_float_cmp(VALUE x, VALUE y)
Definition: numeric.c:1521
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
RFLOAT
#define RFLOAT(obj)
Definition: numeric.h:44
rb_float_minus
VALUE rb_float_minus(VALUE x, VALUE y)
Definition: numeric.c:1078
ROUND_DEFAULT
#define ROUND_DEFAULT
Definition: numeric.h:29
rb_int_plus
VALUE rb_int_plus(VALUE x, VALUE y)
Definition: numeric.c:3597
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
vm.h
Internal header for RubyVM.
rb_method_basic_definition_p
#define rb_method_basic_definition_p(...)
Definition: internal.h:78
int
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
INT2FIX
#define INT2FIX
Definition: long.h:48
ruby.h
Qundef
#define Qundef
Definition: special_consts.h:53
RTEST
#define RTEST
Definition: special_consts.h:42
FIXNUM_P
#define FIXNUM_P
Definition: special_consts.h:44
RBasic
Definition: rbasic.h:47
RFloat
Definition: numeric.h:39
RFloat::float_value
double float_value
Definition: numeric.h:41
RFloat::basic
struct RBasic basic
Definition: numeric.h:40
t
#define t
Definition: symbol.c:253
VALUE
unsigned long VALUE
Definition: value.h:38
ID
unsigned long ID
Definition: value.h:39
T_BIGNUM
#define T_BIGNUM
Definition: value_type.h:56