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
31enum 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
44typedef double rb_float_value_type;
53 rb_float_value_type float_value;
56#define RFLOAT(obj) ((struct RFloat *)(obj))
59int rb_num_to_uint(
VALUE val,
unsigned int *ret);
61double ruby_float_step_size(
double beg,
double end,
double unit,
int excl);
62int ruby_float_step(
VALUE from,
VALUE to,
VALUE step,
int excl,
int allow_endless);
63int rb_num_negative_p(
VALUE);
80enum ruby_num_rounding_mode rb_num_get_rounding_option(
VALUE opts);
91int rb_int_positive_p(
VALUE num);
92int rb_int_negative_p(
VALUE num);
98static inline VALUE rb_num_compare_with_zero(
VALUE num,
ID mid);
99static inline int rb_num_positive_int_p(
VALUE num);
100static inline int rb_num_negative_int_p(
VALUE num);
101static inline double rb_float_flonum_value(
VALUE v);
102static inline double rb_float_noflonum_value(
VALUE v);
103static inline double rb_float_value_inline(
VALUE v);
104static inline VALUE rb_float_new_inline(
double d);
105static inline bool INT_POSITIVE_P(
VALUE num);
106static inline bool INT_NEGATIVE_P(
VALUE num);
107static 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
111RUBY_SYMBOL_EXPORT_BEGIN
113RUBY_SYMBOL_EXPORT_END
116double ruby_float_mod(
double x,
double y);
130INT_POSITIVE_P(
VALUE num)
133 return FIXNUM_POSITIVE_P(num);
136 return BIGNUM_POSITIVE_P(num);
141INT_NEGATIVE_P(
VALUE num)
144 return FIXNUM_NEGATIVE_P(num);
147 return BIGNUM_NEGATIVE_P(num);
152FLOAT_ZERO_P(
VALUE num)
158rb_num_compare_with_zero(
VALUE num,
ID mid)
163 rb_cmperr(num, zero);
169rb_num_positive_int_p(
VALUE num)
174 if (rb_method_basic_definition_p(
rb_cInteger, mid))
175 return FIXNUM_POSITIVE_P(num);
178 if (rb_method_basic_definition_p(
rb_cInteger, mid))
179 return BIGNUM_POSITIVE_P(num);
181 return RTEST(rb_num_compare_with_zero(num, mid));
185rb_num_negative_int_p(
VALUE num)
190 if (rb_method_basic_definition_p(
rb_cInteger, mid))
191 return FIXNUM_NEGATIVE_P(num);
194 if (rb_method_basic_definition_p(
rb_cInteger, mid))
195 return BIGNUM_NEGATIVE_P(num);
197 return RTEST(rb_num_compare_with_zero(num, mid));
201rb_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);
222rb_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};
236rb_float_value_inline(
VALUE v)
239 return rb_float_flonum_value(v);
241 return rb_float_noflonum_value(v);
245rb_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.
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.