зеркало из https://github.com/github/ruby.git
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:
Родитель
235e7738d6
Коммит
f830ace8a8
|
@ -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
|
||||
|
|
45
internal.h
45
internal.h
|
@ -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
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
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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче