@@ -2903,33 +2903,84 @@ rb_str_to_dbl(VALUE str, int badcheck)
2903
2903
return ret ;
2904
2904
}
2905
2905
2906
+ #define fix2dbl_without_to_f (x ) (double)FIX2LONG(x)
2907
+ #define big2dbl_without_to_f (x ) rb_big2dbl(x)
2908
+ #define int2dbl_without_to_f (x ) \
2909
+ (FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x))
2910
+ #define rat2dbl_without_to_f (x ) \
2911
+ (int2dbl_without_to_f(rb_rational_num(x)) / \
2912
+ int2dbl_without_to_f(rb_rational_den(x)))
2913
+
2914
+ #define special_const_to_float (val , pre , post ) \
2915
+ switch (val) { \
2916
+ case Qnil: \
2917
+ rb_raise(rb_eTypeError, pre "nil" post); \
2918
+ case Qtrue: \
2919
+ rb_raise(rb_eTypeError, pre "true" post); \
2920
+ case Qfalse: \
2921
+ rb_raise(rb_eTypeError, pre "false" post); \
2922
+ }
2923
+
2924
+ static inline void
2925
+ conversion_to_float (VALUE val )
2926
+ {
2927
+ special_const_to_float (val , "can't convert " , " into Float" );
2928
+ }
2929
+
2930
+ static inline void
2931
+ implicit_conversion_to_float (VALUE val )
2932
+ {
2933
+ special_const_to_float (val , "no implicit conversion to float from " , "" );
2934
+ }
2935
+
2936
+ static int
2937
+ to_float (VALUE * valp )
2938
+ {
2939
+ VALUE val = * valp ;
2940
+ if (SPECIAL_CONST_P (val )) {
2941
+ if (FIXNUM_P (val )) {
2942
+ * valp = DBL2NUM (fix2dbl_without_to_f (val ));
2943
+ return T_FLOAT ;
2944
+ }
2945
+ else if (FLONUM_P (val )) {
2946
+ return T_FLOAT ;
2947
+ }
2948
+ else {
2949
+ conversion_to_float (val );
2950
+ }
2951
+ }
2952
+ else {
2953
+ int type = BUILTIN_TYPE (val );
2954
+ switch (type ) {
2955
+ case T_FLOAT :
2956
+ return T_FLOAT ;
2957
+ case T_BIGNUM :
2958
+ * valp = DBL2NUM (big2dbl_without_to_f (val ));
2959
+ return T_FLOAT ;
2960
+ case T_RATIONAL :
2961
+ * valp = DBL2NUM (rat2dbl_without_to_f (val ));
2962
+ return T_FLOAT ;
2963
+ case T_STRING :
2964
+ return T_STRING ;
2965
+ }
2966
+ }
2967
+ return T_NONE ;
2968
+ }
2969
+
2906
2970
VALUE
2907
2971
rb_Float (VALUE val )
2908
2972
{
2909
- switch (TYPE (val )) {
2910
- case T_FIXNUM :
2911
- return DBL2NUM ((double )FIX2LONG (val ));
2912
-
2973
+ switch (to_float (& val )) {
2913
2974
case T_FLOAT :
2914
2975
return val ;
2915
-
2916
- case T_BIGNUM :
2917
- return DBL2NUM (rb_big2dbl (val ));
2918
-
2919
2976
case T_STRING :
2920
2977
return DBL2NUM (rb_str_to_dbl (val , TRUE));
2921
-
2922
- case T_NIL :
2923
- rb_raise (rb_eTypeError , "can't convert nil into Float" );
2924
- break ;
2925
-
2926
- default :
2927
- return rb_convert_type (val , T_FLOAT , "Float" , "to_f" );
2928
2978
}
2929
-
2930
- UNREACHABLE ;
2979
+ return rb_convert_type (val , T_FLOAT , "Float" , "to_f" );
2931
2980
}
2932
2981
2982
+ FUNC_MINIMIZED (static VALUE rb_f_float (VALUE obj , VALUE arg ));
2983
+
2933
2984
/*
2934
2985
* call-seq:
2935
2986
* Float(arg) -> float
@@ -2948,20 +2999,26 @@ rb_f_float(VALUE obj, VALUE arg)
2948
2999
return rb_Float (arg );
2949
3000
}
2950
3001
2951
- VALUE
2952
- rb_to_float (VALUE val )
3002
+ static VALUE
3003
+ numeric_to_float (VALUE val )
2953
3004
{
2954
- if (RB_TYPE_P (val , T_FLOAT )) return val ;
2955
3005
if (!rb_obj_is_kind_of (val , rb_cNumeric )) {
2956
- rb_raise (rb_eTypeError , "can't convert %s into Float" ,
2957
- NIL_P (val ) ? "nil" :
2958
- val == Qtrue ? "true" :
2959
- val == Qfalse ? "false" :
2960
- rb_obj_classname (val ));
3006
+ rb_raise (rb_eTypeError , "can't convert %" PRIsVALUE " into Float" ,
3007
+ rb_obj_class (val ));
2961
3008
}
2962
3009
return rb_convert_type (val , T_FLOAT , "Float" , "to_f" );
2963
3010
}
2964
3011
3012
+ VALUE
3013
+ rb_to_float (VALUE val )
3014
+ {
3015
+ switch (to_float (& val )) {
3016
+ case T_FLOAT :
3017
+ return val ;
3018
+ }
3019
+ return numeric_to_float (val );
3020
+ }
3021
+
2965
3022
VALUE
2966
3023
rb_check_to_float (VALUE val )
2967
3024
{
@@ -2972,26 +3029,75 @@ rb_check_to_float(VALUE val)
2972
3029
return rb_check_convert_type (val , T_FLOAT , "Float" , "to_f" );
2973
3030
}
2974
3031
2975
- double
2976
- rb_num2dbl (VALUE val )
2977
- {
2978
- switch (TYPE (val )) {
2979
- case T_FLOAT :
2980
- return RFLOAT_VALUE (val );
2981
-
2982
- case T_STRING :
2983
- rb_raise (rb_eTypeError , "no implicit conversion to float from string" );
2984
- break ;
3032
+ static ID id_to_f ;
2985
3033
2986
- case T_NIL :
2987
- rb_raise (rb_eTypeError , "no implicit conversion to float from nil" );
2988
- break ;
3034
+ static inline int
3035
+ basic_to_f_p (VALUE klass )
3036
+ {
3037
+ return rb_method_basic_definition_p (klass , id_to_f );
3038
+ }
2989
3039
2990
- default :
2991
- break ;
3040
+ double
3041
+ rb_num_to_dbl (VALUE val )
3042
+ {
3043
+ if (SPECIAL_CONST_P (val )) {
3044
+ if (FIXNUM_P (val )) {
3045
+ if (basic_to_f_p (rb_cFixnum ))
3046
+ return fix2dbl_without_to_f (val );
3047
+ }
3048
+ else if (FLONUM_P (val )) {
3049
+ return rb_float_flonum_value (val );
3050
+ }
3051
+ else {
3052
+ conversion_to_float (val );
3053
+ }
2992
3054
}
3055
+ else {
3056
+ switch (BUILTIN_TYPE (val )) {
3057
+ case T_FLOAT :
3058
+ return rb_float_noflonum_value (val );
3059
+ case T_BIGNUM :
3060
+ if (basic_to_f_p (rb_cBignum ))
3061
+ return big2dbl_without_to_f (val );
3062
+ break ;
3063
+ case T_RATIONAL :
3064
+ if (basic_to_f_p (rb_cRational ))
3065
+ return rat2dbl_without_to_f (val );
3066
+ break ;
3067
+ }
3068
+ }
3069
+ val = numeric_to_float (val );
3070
+ return RFLOAT_VALUE (val );
3071
+ }
2993
3072
2994
- return RFLOAT_VALUE (rb_Float (val ));
3073
+ double
3074
+ rb_num2dbl (VALUE val )
3075
+ {
3076
+ if (SPECIAL_CONST_P (val )) {
3077
+ if (FIXNUM_P (val )) {
3078
+ return fix2dbl_without_to_f (val );
3079
+ }
3080
+ else if (FLONUM_P (val )) {
3081
+ return rb_float_flonum_value (val );
3082
+ }
3083
+ else {
3084
+ implicit_conversion_to_float (val );
3085
+ }
3086
+ }
3087
+ else {
3088
+ switch (BUILTIN_TYPE (val )) {
3089
+ case T_FLOAT :
3090
+ return rb_float_noflonum_value (val );
3091
+ case T_BIGNUM :
3092
+ return big2dbl_without_to_f (val );
3093
+ case T_RATIONAL :
3094
+ return rat2dbl_without_to_f (val );
3095
+ case T_STRING :
3096
+ rb_raise (rb_eTypeError , "no implicit conversion to float from string" );
3097
+ }
3098
+ }
3099
+ val = rb_convert_type (val , T_FLOAT , "Float" , "to_f" );
3100
+ return RFLOAT_VALUE (val );
2995
3101
}
2996
3102
2997
3103
VALUE
@@ -3243,7 +3349,7 @@ rb_f_hash(VALUE obj, VALUE arg)
3243
3349
*/
3244
3350
3245
3351
void
3246
- Init_Object (void )
3352
+ InitVM_Object (void )
3247
3353
{
3248
3354
Init_class_hierarchy ();
3249
3355
@@ -3461,3 +3567,10 @@ Init_Object(void)
3461
3567
*/
3462
3568
rb_define_global_const ("FALSE" , Qfalse );
3463
3569
}
3570
+
3571
+ void
3572
+ Init_Object (void )
3573
+ {
3574
+ id_to_f = rb_intern_const ("to_f" );
3575
+ InitVM (Object );
3576
+ }
0 commit comments