diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-25 07:58:49 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-25 07:58:49 +0000 |
commit | d700d340437a4cfba215e51b9045460900c62c3a (patch) | |
tree | 6eab445cde1fc6e53ff86ba9718180baaeb609e3 /internal.h | |
parent | b328a43fa6e9d07ee8cfce09aaf5fdf1da7203fd (diff) | |
download | ruby-d700d340437a4cfba215e51b9045460900c62c3a.tar.gz |
internal.h: move inline functions
* internal.h (rb_float_value, rb_float_new): move inline functions
from ruby/ruby.h.
* numeric.c (rb_float_value, rb_float_new): define external functions
for extension libraries.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43042 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'internal.h')
-rw-r--r-- | internal.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/internal.h b/internal.h index 424f6f5d8f..7c5a42a521 100644 --- a/internal.h +++ b/internal.h @@ -478,6 +478,70 @@ int rb_num_negative_p(VALUE); VALUE rb_int_succ(VALUE num); VALUE rb_int_pred(VALUE num); +#if USE_FLONUM +#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n))) +#define RUBY_BIT_ROTR(v, n) (((v) >> (n)) | ((v) << ((sizeof(v) * 8) - n))) +#endif + +static inline double +rb_float_value_inline(VALUE v) +{ +#if USE_FLONUM + if (FLONUM_P(v)) { + if (v != (VALUE)0x8000000000000002) { /* LIKELY */ + union { + double d; + VALUE v; + } t; + + VALUE b63 = (v >> 63); + /* e: xx1... -> 011... */ + /* xx0... -> 100... */ + /* ^b63 */ + t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~0x03), 3); + return t.d; + } + else { + return 0.0; + } + } +#endif + return ((struct RFloat *)v)->float_value; +} + +static inline VALUE +rb_float_new_inline(double d) +{ +#if USE_FLONUM + union { + double d; + VALUE v; + } t; + int bits; + + t.d = d; + bits = (int)((VALUE)(t.v >> 60) & 0x7); + /* bits contains 3 bits of b62..b60. */ + /* bits - 3 = */ + /* b011 -> b000 */ + /* b100 -> b001 */ + + if (t.v != 0x3000000000000000 /* 1.72723e-77 */ && + !((bits-3) & ~0x01)) { + return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02; + } + else if (t.v == (VALUE)0) { + /* +0.0 */ + return 0x8000000000000002; + } + /* out of range */ +#endif + return rb_float_new_in_heap(d); +} + +#define rb_float_value(v) rb_float_value_inline(v) +#define rb_float_new(d) rb_float_new_inline(d) + /* object.c */ VALUE rb_obj_equal(VALUE obj1, VALUE obj2); |