* 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:
nobu 2015-08-13 05:36:33 +00:00
Родитель 235e7738d6
Коммит f830ace8a8
4 изменённых файлов: 188 добавлений и 105 удалений

Просмотреть файл

@ -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>
* load.c (features_index_add): avoid repeat calculation

Просмотреть файл

@ -903,31 +903,41 @@ VALUE rb_dbl_hash(double d);
#endif
static inline double
rb_float_value_inline(VALUE v)
rb_float_flonum_value(VALUE v)
{
#if USE_FLONUM
if (FLONUM_P(v)) {
if (v != (VALUE)0x8000000000000002) { /* LIKELY */
union {
double d;
VALUE v;
} t;
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;
}
VALUE b63 = (v >> 63);
/* e: xx1... -> 011... */
/* xx0... -> 100... */
/* ^b63 */
t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~0x03), 3);
return t.d;
}
#endif
return 0.0;
}
static inline double
rb_float_noflonum_value(VALUE v)
{
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
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);
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
double rb_num_to_dbl(VALUE val);
struct RBasicRaw {
VALUE flags;

47
math.c
Просмотреть файл

@ -21,54 +21,10 @@
#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
static ID id_to_f;
VALUE rb_mMath;
VALUE rb_eMathDomainError;
static inline int
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 Get_Double(x) rb_num_to_dbl(x)
#define domain_error(msg) \
rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
@ -1024,6 +980,5 @@ InitVM_Math(void)
void
Init_Math(void)
{
id_to_f = rb_intern_const("to_f");
InitVM(Math);
}

197
object.c
Просмотреть файл

@ -2903,33 +2903,84 @@ rb_str_to_dbl(VALUE str, int badcheck)
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
rb_Float(VALUE val)
{
switch (TYPE(val)) {
case T_FIXNUM:
return DBL2NUM((double)FIX2LONG(val));
switch (to_float(&val)) {
case T_FLOAT:
return val;
case T_BIGNUM:
return DBL2NUM(rb_big2dbl(val));
case T_STRING:
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");
}
UNREACHABLE;
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
}
FUNC_MINIMIZED(static VALUE rb_f_float(VALUE obj, VALUE arg));
/*
* call-seq:
* Float(arg) -> float
@ -2948,18 +2999,24 @@ rb_f_float(VALUE obj, VALUE 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
rb_to_float(VALUE val)
{
if (RB_TYPE_P(val, T_FLOAT)) return val;
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
rb_raise(rb_eTypeError, "can't convert %s into Float",
NIL_P(val) ? "nil" :
val == Qtrue ? "true" :
val == Qfalse ? "false" :
rb_obj_classname(val));
switch (to_float(&val)) {
case T_FLOAT:
return val;
}
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
return numeric_to_float(val);
}
VALUE
@ -2972,26 +3029,75 @@ rb_check_to_float(VALUE val)
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
rb_num2dbl(VALUE val)
{
switch (TYPE(val)) {
case T_FLOAT:
return RFLOAT_VALUE(val);
case T_STRING:
rb_raise(rb_eTypeError, "no implicit conversion to float from string");
break;
case T_NIL:
rb_raise(rb_eTypeError, "no implicit conversion to float from nil");
break;
default:
break;
if (SPECIAL_CONST_P(val)) {
if (FIXNUM_P(val)) {
return fix2dbl_without_to_f(val);
}
else if (FLONUM_P(val)) {
return rb_float_flonum_value(val);
}
else {
implicit_conversion_to_float(val);
}
}
return RFLOAT_VALUE(rb_Float(val));
else {
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
@ -3243,7 +3349,7 @@ rb_f_hash(VALUE obj, VALUE arg)
*/
void
Init_Object(void)
InitVM_Object(void)
{
Init_class_hierarchy();
@ -3461,3 +3567,10 @@ Init_Object(void)
*/
rb_define_global_const("FALSE", Qfalse);
}
void
Init_Object(void)
{
id_to_f = rb_intern_const("to_f");
InitVM(Object);
}