mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
object.c: rb_num_to_dbl
* object.c (rb_num_to_dbl): move from num2dbl_with_to_f in math.c. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51563 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
235e7738d6
commit
f830ace8a8
4 changed files with 188 additions and 105 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Thu Aug 13 14:36:31 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* object.c (rb_num_to_dbl): move from num2dbl_with_to_f in math.c.
|
||||||
|
|
||||||
Thu Aug 13 09:01:25 2015 Eric Wong <e@80x24.org>
|
Thu Aug 13 09:01:25 2015 Eric Wong <e@80x24.org>
|
||||||
|
|
||||||
* load.c (features_index_add): avoid repeat calculation
|
* load.c (features_index_add): avoid repeat calculation
|
||||||
|
|
45
internal.h
45
internal.h
|
@ -903,31 +903,41 @@ VALUE rb_dbl_hash(double d);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline double
|
static inline double
|
||||||
rb_float_value_inline(VALUE v)
|
rb_float_flonum_value(VALUE v)
|
||||||
{
|
{
|
||||||
#if USE_FLONUM
|
#if USE_FLONUM
|
||||||
if (FLONUM_P(v)) {
|
if (v != (VALUE)0x8000000000000002) { /* LIKELY */
|
||||||
if (v != (VALUE)0x8000000000000002) { /* LIKELY */
|
union {
|
||||||
union {
|
double d;
|
||||||
double d;
|
VALUE v;
|
||||||
VALUE v;
|
} t;
|
||||||
} t;
|
|
||||||
|
|
||||||
VALUE b63 = (v >> 63);
|
VALUE b63 = (v >> 63);
|
||||||
/* e: xx1... -> 011... */
|
/* e: xx1... -> 011... */
|
||||||
/* xx0... -> 100... */
|
/* xx0... -> 100... */
|
||||||
/* ^b63 */
|
/* ^b63 */
|
||||||
t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~0x03), 3);
|
t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~0x03), 3);
|
||||||
return t.d;
|
return t.d;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
rb_float_noflonum_value(VALUE v)
|
||||||
|
{
|
||||||
return ((struct RFloat *)v)->float_value;
|
return ((struct RFloat *)v)->float_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
rb_float_value_inline(VALUE v)
|
||||||
|
{
|
||||||
|
if (FLONUM_P(v)) {
|
||||||
|
return rb_float_flonum_value(v);
|
||||||
|
}
|
||||||
|
return rb_float_noflonum_value(v);
|
||||||
|
}
|
||||||
|
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
rb_float_new_inline(double d)
|
rb_float_new_inline(double d)
|
||||||
{
|
{
|
||||||
|
@ -965,6 +975,7 @@ rb_float_new_inline(double d)
|
||||||
void rb_obj_copy_ivar(VALUE dest, VALUE obj);
|
void rb_obj_copy_ivar(VALUE dest, VALUE obj);
|
||||||
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
|
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
|
||||||
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
|
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
|
||||||
|
double rb_num_to_dbl(VALUE val);
|
||||||
|
|
||||||
struct RBasicRaw {
|
struct RBasicRaw {
|
||||||
VALUE flags;
|
VALUE flags;
|
||||||
|
|
47
math.c
47
math.c
|
@ -21,54 +21,10 @@
|
||||||
|
|
||||||
#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
|
#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
|
||||||
|
|
||||||
static ID id_to_f;
|
|
||||||
|
|
||||||
VALUE rb_mMath;
|
VALUE rb_mMath;
|
||||||
VALUE rb_eMathDomainError;
|
VALUE rb_eMathDomainError;
|
||||||
|
|
||||||
static inline int
|
#define Get_Double(x) rb_num_to_dbl(x)
|
||||||
basic_to_f_p(VALUE klass)
|
|
||||||
{
|
|
||||||
return rb_method_basic_definition_p(klass, id_to_f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define fix2dbl_without_to_f(x) (double)FIX2LONG(x)
|
|
||||||
#define big2dbl_without_to_f(x) rb_big2dbl(x)
|
|
||||||
#define int2dbl_without_to_f(x) (FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x))
|
|
||||||
#define rat2dbl_without_to_f(x) \
|
|
||||||
(int2dbl_without_to_f(rb_rational_num(x)) / \
|
|
||||||
int2dbl_without_to_f(rb_rational_den(x)))
|
|
||||||
|
|
||||||
static inline double
|
|
||||||
num2dbl_with_to_f(VALUE num)
|
|
||||||
{
|
|
||||||
if (SPECIAL_CONST_P(num)) {
|
|
||||||
if (FIXNUM_P(num)) {
|
|
||||||
if (basic_to_f_p(rb_cFixnum))
|
|
||||||
return fix2dbl_without_to_f(num);
|
|
||||||
}
|
|
||||||
else if (FLONUM_P(num)) {
|
|
||||||
return RFLOAT_VALUE(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (BUILTIN_TYPE(num)) {
|
|
||||||
case T_FLOAT:
|
|
||||||
return RFLOAT_VALUE(num);
|
|
||||||
case T_BIGNUM:
|
|
||||||
if (basic_to_f_p(rb_cBignum))
|
|
||||||
return big2dbl_without_to_f(num);
|
|
||||||
break;
|
|
||||||
case T_RATIONAL:
|
|
||||||
if (basic_to_f_p(rb_cRational))
|
|
||||||
return rat2dbl_without_to_f(num);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return RFLOAT_VALUE(rb_to_float(num));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define Get_Double(x) num2dbl_with_to_f(x)
|
|
||||||
|
|
||||||
#define domain_error(msg) \
|
#define domain_error(msg) \
|
||||||
rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
|
rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
|
||||||
|
@ -1024,6 +980,5 @@ InitVM_Math(void)
|
||||||
void
|
void
|
||||||
Init_Math(void)
|
Init_Math(void)
|
||||||
{
|
{
|
||||||
id_to_f = rb_intern_const("to_f");
|
|
||||||
InitVM(Math);
|
InitVM(Math);
|
||||||
}
|
}
|
||||||
|
|
197
object.c
197
object.c
|
@ -2903,33 +2903,84 @@ rb_str_to_dbl(VALUE str, int badcheck)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define fix2dbl_without_to_f(x) (double)FIX2LONG(x)
|
||||||
|
#define big2dbl_without_to_f(x) rb_big2dbl(x)
|
||||||
|
#define int2dbl_without_to_f(x) \
|
||||||
|
(FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x))
|
||||||
|
#define rat2dbl_without_to_f(x) \
|
||||||
|
(int2dbl_without_to_f(rb_rational_num(x)) / \
|
||||||
|
int2dbl_without_to_f(rb_rational_den(x)))
|
||||||
|
|
||||||
|
#define special_const_to_float(val, pre, post) \
|
||||||
|
switch (val) { \
|
||||||
|
case Qnil: \
|
||||||
|
rb_raise(rb_eTypeError, pre "nil" post); \
|
||||||
|
case Qtrue: \
|
||||||
|
rb_raise(rb_eTypeError, pre "true" post); \
|
||||||
|
case Qfalse: \
|
||||||
|
rb_raise(rb_eTypeError, pre "false" post); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
conversion_to_float(VALUE val)
|
||||||
|
{
|
||||||
|
special_const_to_float(val, "can't convert ", " into Float");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
implicit_conversion_to_float(VALUE val)
|
||||||
|
{
|
||||||
|
special_const_to_float(val, "no implicit conversion to float from ", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
to_float(VALUE *valp)
|
||||||
|
{
|
||||||
|
VALUE val = *valp;
|
||||||
|
if (SPECIAL_CONST_P(val)) {
|
||||||
|
if (FIXNUM_P(val)) {
|
||||||
|
*valp = DBL2NUM(fix2dbl_without_to_f(val));
|
||||||
|
return T_FLOAT;
|
||||||
|
}
|
||||||
|
else if (FLONUM_P(val)) {
|
||||||
|
return T_FLOAT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
conversion_to_float(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int type = BUILTIN_TYPE(val);
|
||||||
|
switch (type) {
|
||||||
|
case T_FLOAT:
|
||||||
|
return T_FLOAT;
|
||||||
|
case T_BIGNUM:
|
||||||
|
*valp = DBL2NUM(big2dbl_without_to_f(val));
|
||||||
|
return T_FLOAT;
|
||||||
|
case T_RATIONAL:
|
||||||
|
*valp = DBL2NUM(rat2dbl_without_to_f(val));
|
||||||
|
return T_FLOAT;
|
||||||
|
case T_STRING:
|
||||||
|
return T_STRING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return T_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_Float(VALUE val)
|
rb_Float(VALUE val)
|
||||||
{
|
{
|
||||||
switch (TYPE(val)) {
|
switch (to_float(&val)) {
|
||||||
case T_FIXNUM:
|
|
||||||
return DBL2NUM((double)FIX2LONG(val));
|
|
||||||
|
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
return val;
|
return val;
|
||||||
|
|
||||||
case T_BIGNUM:
|
|
||||||
return DBL2NUM(rb_big2dbl(val));
|
|
||||||
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
return DBL2NUM(rb_str_to_dbl(val, TRUE));
|
return DBL2NUM(rb_str_to_dbl(val, TRUE));
|
||||||
|
|
||||||
case T_NIL:
|
|
||||||
rb_raise(rb_eTypeError, "can't convert nil into Float");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
|
|
||||||
}
|
}
|
||||||
|
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
|
||||||
UNREACHABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FUNC_MINIMIZED(static VALUE rb_f_float(VALUE obj, VALUE arg));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Float(arg) -> float
|
* Float(arg) -> float
|
||||||
|
@ -2948,18 +2999,24 @@ rb_f_float(VALUE obj, VALUE arg)
|
||||||
return rb_Float(arg);
|
return rb_Float(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
numeric_to_float(VALUE val)
|
||||||
|
{
|
||||||
|
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
|
||||||
|
rb_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into Float",
|
||||||
|
rb_obj_class(val));
|
||||||
|
}
|
||||||
|
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_to_float(VALUE val)
|
rb_to_float(VALUE val)
|
||||||
{
|
{
|
||||||
if (RB_TYPE_P(val, T_FLOAT)) return val;
|
switch (to_float(&val)) {
|
||||||
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
|
case T_FLOAT:
|
||||||
rb_raise(rb_eTypeError, "can't convert %s into Float",
|
return val;
|
||||||
NIL_P(val) ? "nil" :
|
|
||||||
val == Qtrue ? "true" :
|
|
||||||
val == Qfalse ? "false" :
|
|
||||||
rb_obj_classname(val));
|
|
||||||
}
|
}
|
||||||
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
|
return numeric_to_float(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -2972,26 +3029,75 @@ rb_check_to_float(VALUE val)
|
||||||
return rb_check_convert_type(val, T_FLOAT, "Float", "to_f");
|
return rb_check_convert_type(val, T_FLOAT, "Float", "to_f");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ID id_to_f;
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
basic_to_f_p(VALUE klass)
|
||||||
|
{
|
||||||
|
return rb_method_basic_definition_p(klass, id_to_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
rb_num_to_dbl(VALUE val)
|
||||||
|
{
|
||||||
|
if (SPECIAL_CONST_P(val)) {
|
||||||
|
if (FIXNUM_P(val)) {
|
||||||
|
if (basic_to_f_p(rb_cFixnum))
|
||||||
|
return fix2dbl_without_to_f(val);
|
||||||
|
}
|
||||||
|
else if (FLONUM_P(val)) {
|
||||||
|
return rb_float_flonum_value(val);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
conversion_to_float(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (BUILTIN_TYPE(val)) {
|
||||||
|
case T_FLOAT:
|
||||||
|
return rb_float_noflonum_value(val);
|
||||||
|
case T_BIGNUM:
|
||||||
|
if (basic_to_f_p(rb_cBignum))
|
||||||
|
return big2dbl_without_to_f(val);
|
||||||
|
break;
|
||||||
|
case T_RATIONAL:
|
||||||
|
if (basic_to_f_p(rb_cRational))
|
||||||
|
return rat2dbl_without_to_f(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val = numeric_to_float(val);
|
||||||
|
return RFLOAT_VALUE(val);
|
||||||
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
rb_num2dbl(VALUE val)
|
rb_num2dbl(VALUE val)
|
||||||
{
|
{
|
||||||
switch (TYPE(val)) {
|
if (SPECIAL_CONST_P(val)) {
|
||||||
case T_FLOAT:
|
if (FIXNUM_P(val)) {
|
||||||
return RFLOAT_VALUE(val);
|
return fix2dbl_without_to_f(val);
|
||||||
|
}
|
||||||
case T_STRING:
|
else if (FLONUM_P(val)) {
|
||||||
rb_raise(rb_eTypeError, "no implicit conversion to float from string");
|
return rb_float_flonum_value(val);
|
||||||
break;
|
}
|
||||||
|
else {
|
||||||
case T_NIL:
|
implicit_conversion_to_float(val);
|
||||||
rb_raise(rb_eTypeError, "no implicit conversion to float from nil");
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return RFLOAT_VALUE(rb_Float(val));
|
switch (BUILTIN_TYPE(val)) {
|
||||||
|
case T_FLOAT:
|
||||||
|
return rb_float_noflonum_value(val);
|
||||||
|
case T_BIGNUM:
|
||||||
|
return big2dbl_without_to_f(val);
|
||||||
|
case T_RATIONAL:
|
||||||
|
return rat2dbl_without_to_f(val);
|
||||||
|
case T_STRING:
|
||||||
|
rb_raise(rb_eTypeError, "no implicit conversion to float from string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val = rb_convert_type(val, T_FLOAT, "Float", "to_f");
|
||||||
|
return RFLOAT_VALUE(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -3243,7 +3349,7 @@ rb_f_hash(VALUE obj, VALUE arg)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_Object(void)
|
InitVM_Object(void)
|
||||||
{
|
{
|
||||||
Init_class_hierarchy();
|
Init_class_hierarchy();
|
||||||
|
|
||||||
|
@ -3461,3 +3567,10 @@ Init_Object(void)
|
||||||
*/
|
*/
|
||||||
rb_define_global_const("FALSE", Qfalse);
|
rb_define_global_const("FALSE", Qfalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init_Object(void)
|
||||||
|
{
|
||||||
|
id_to_f = rb_intern_const("to_f");
|
||||||
|
InitVM(Object);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue