mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Add new range check macro FIXABLE_FLOAT(); ref #3652
When MRB_INT64, valid value range of mrb_int is bigger than double, which only has 53 bits significant precision.
This commit is contained in:
@@ -20,6 +20,12 @@ MRB_BEGIN_DECL
|
||||
#define NEGFIXABLE(f) ((f) >= MRB_INT_MIN)
|
||||
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
|
||||
|
||||
#ifdef MRB_INT64
|
||||
#define FIXABLE_FLOAT(f) FIXABLE((mrb_int)(f))
|
||||
#else
|
||||
#define FIXABLE_FLOAT(f) FIXABLE(f)
|
||||
#endif
|
||||
|
||||
MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
|
||||
MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base);
|
||||
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
|
||||
|
||||
+1
-1
@@ -800,7 +800,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
{
|
||||
mrb_float f = mrb_float(ARGV[arg_i]);
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
if (!FIXABLE_FLOAT(f)) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
|
||||
}
|
||||
*p = (mrb_int)f;
|
||||
|
||||
+5
-5
@@ -392,7 +392,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
|
||||
val *= 2;
|
||||
}
|
||||
}
|
||||
if (FIXABLE(val)) {
|
||||
if (FIXABLE_FLOAT(val)) {
|
||||
return mrb_fixnum_value((mrb_int)val);
|
||||
}
|
||||
return mrb_float_value(mrb, val);
|
||||
@@ -515,7 +515,7 @@ flo_floor(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
mrb_float f = floor(mrb_float(num));
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
if (!FIXABLE_FLOAT(f)) {
|
||||
return mrb_float_value(mrb, f);
|
||||
}
|
||||
return mrb_fixnum_value((mrb_int)f);
|
||||
@@ -540,7 +540,7 @@ flo_ceil(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
mrb_float f = ceil(mrb_float(num));
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
if (!FIXABLE_FLOAT(f)) {
|
||||
return mrb_float_value(mrb, f);
|
||||
}
|
||||
return mrb_fixnum_value((mrb_int)f);
|
||||
@@ -661,7 +661,7 @@ flo_truncate(mrb_state *mrb, mrb_value num)
|
||||
if (f > 0.0) f = floor(f);
|
||||
if (f < 0.0) f = ceil(f);
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
if (!FIXABLE_FLOAT(f)) {
|
||||
mrb_check_num_exact(mrb, f);
|
||||
return mrb_float_value(mrb, f);
|
||||
}
|
||||
@@ -1099,7 +1099,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
|
||||
if (isnan(d)) {
|
||||
mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
|
||||
}
|
||||
if (FIXABLE(d)) {
|
||||
if (FIXABLE_FLOAT(d)) {
|
||||
z = (mrb_int)d;
|
||||
}
|
||||
else {
|
||||
|
||||
+5
-2
@@ -534,8 +534,11 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_FLOAT:
|
||||
if (base != 0) goto arg_error;
|
||||
if (FIXABLE(mrb_float(val))) {
|
||||
break;
|
||||
else {
|
||||
mrb_float f = mrb_float(val);
|
||||
if (FIXABLE_FLOAT(f)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mrb_flo_to_fixnum(mrb, val);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user