1 #ifndef INTERNAL_NUMERIC_H
2 #define INTERNAL_NUMERIC_H
11 #include "internal/bignum.h"
12 #include "internal/bits.h"
13 #include "internal/fixnum.h"
14 #include "internal/vm.h"
18 #define ROUND_TO(mode, even, up, down) \
19 ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \
20 (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
21 #define ROUND_FUNC(mode, name) \
22 ROUND_TO(mode, name##_half_even, name##_half_up, name##_half_down)
23 #define ROUND_CALL(mode, name, args) \
24 ROUND_TO(mode, name##_half_even args, \
25 name##_half_up args, name##_half_down args)
28 # define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
31 enum ruby_num_rounding_mode {
32 RUBY_NUM_ROUND_HALF_UP,
33 RUBY_NUM_ROUND_HALF_EVEN,
34 RUBY_NUM_ROUND_HALF_DOWN,
35 RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT,
39 #define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
40 #define roomof(x, y) (((x) + (y) - 1) / (y))
41 #define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
43 #if SIZEOF_DOUBLE <= SIZEOF_VALUE
44 typedef double rb_float_value_type;
48 } rb_float_value_type;
53 rb_float_value_type float_value;
56 #define RFLOAT(obj) ((struct RFloat *)(obj))
59 int rb_num_to_uint(
VALUE val,
unsigned int *ret);
61 double ruby_float_step_size(
double beg,
double end,
double unit,
int excl);
62 int ruby_float_step(
VALUE from,
VALUE to,
VALUE step,
int excl,
int allow_endless);
63 int rb_num_negative_p(
VALUE);
80 enum ruby_num_rounding_mode rb_num_get_rounding_option(
VALUE opts);
91 int rb_int_positive_p(
VALUE num);
92 int rb_int_negative_p(
VALUE num);
98 static inline VALUE rb_num_compare_with_zero(
VALUE num,
ID mid);
99 static inline int rb_num_positive_int_p(
VALUE num);
100 static inline int rb_num_negative_int_p(
VALUE num);
101 static inline double rb_float_flonum_value(
VALUE v);
102 static inline double rb_float_noflonum_value(
VALUE v);
103 static inline double rb_float_value_inline(
VALUE v);
104 static inline VALUE rb_float_new_inline(
double d);
105 static inline bool INT_POSITIVE_P(
VALUE num);
106 static inline bool INT_NEGATIVE_P(
VALUE num);
107 static inline bool FLOAT_ZERO_P(
VALUE num);
108 #define rb_float_value rb_float_value_inline
109 #define rb_float_new rb_float_new_inline
111 RUBY_SYMBOL_EXPORT_BEGIN
113 RUBY_SYMBOL_EXPORT_END
116 double ruby_float_mod(
double x,
double y);
130 INT_POSITIVE_P(
VALUE num)
133 return FIXNUM_POSITIVE_P(num);
136 return BIGNUM_POSITIVE_P(num);
141 INT_NEGATIVE_P(
VALUE num)
144 return FIXNUM_NEGATIVE_P(num);
147 return BIGNUM_NEGATIVE_P(num);
152 FLOAT_ZERO_P(
VALUE num)
158 rb_num_compare_with_zero(
VALUE num,
ID mid)
169 rb_num_positive_int_p(
VALUE num)
175 return FIXNUM_POSITIVE_P(num);
179 return BIGNUM_POSITIVE_P(num);
181 return RTEST(rb_num_compare_with_zero(num, mid));
185 rb_num_negative_int_p(
VALUE num)
191 return FIXNUM_NEGATIVE_P(num);
195 return BIGNUM_NEGATIVE_P(num);
197 return RTEST(rb_num_compare_with_zero(num, mid));
201 rb_float_flonum_value(
VALUE v)
204 if (v != (
VALUE)0x8000000000000002) {
210 VALUE b63 = (v >> 63);
214 t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(
VALUE)0x03), 3);
222 rb_float_noflonum_value(
VALUE v)
224 #if SIZEOF_DOUBLE <= SIZEOF_VALUE
225 return RFLOAT(v)->float_value;
228 rb_float_value_type v;
230 } u = {RFLOAT(v)->float_value};
236 rb_float_value_inline(
VALUE v)
239 return rb_float_flonum_value(v);
241 return rb_float_noflonum_value(v);
245 rb_float_new_inline(
double d)
255 bits = (int)((
VALUE)(t.v >> 60) & 0x7);
261 if (t.v != 0x3000000000000000 &&
262 !((bits-3) & ~0x01)) {
263 return (RUBY_BIT_ROTL(t.v, 3) & ~(
VALUE)0x01) | 0x02;
265 else if (t.v == (
VALUE)0) {
267 return 0x8000000000000002;
VALUE rb_float_new_in_heap(double d)
Identical to rb_float_new(), except it does not generate Flonums.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define INT2FIX
Old name of RB_INT2FIX.
#define T_BIGNUM
Old name of RUBY_T_BIGNUM.
#define FLONUM_P
Old name of RB_FLONUM_P.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
VALUE rb_cInteger
Module class.
void rb_cmperr(VALUE a, VALUE b)
Raises "comparison failed" error.
int rb_method_basic_definition_p(VALUE klass, ID mid)
Well...
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it returns RUBY_Qundef instead of raising rb_eNoMethodError.
static bool RB_UNDEF_P(VALUE obj)
Checks if the given object is undef.
#define RTEST
This is an old name of RB_TEST.
Ruby object's base components.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.