Commit 0270d11c authored by Yukihiro Matsumoto's avatar Yukihiro Matsumoto

float do not have enough precision to round if MRB_USE_FLOAT is set

parent 1563cdfc
...@@ -195,7 +195,11 @@ flo_to_s(mrb_state *mrb, mrb_value flt) ...@@ -195,7 +195,11 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
} else if(isnan(value)) } else if(isnan(value))
return mrb_str_new(mrb, "NaN", 3); return mrb_str_new(mrb, "NaN", 3);
#ifdef MRB_USE_FLOAT
n = sprintf(buf, "%.7g", value);
#else
n = sprintf(buf, "%.14g", value); n = sprintf(buf, "%.14g", value);
#endif
assert(n >= 0); assert(n >= 0);
return mrb_str_new(mrb, buf, n); return mrb_str_new(mrb, buf, n);
} }
...@@ -511,21 +515,13 @@ flo_ceil(mrb_state *mrb, mrb_value num) ...@@ -511,21 +515,13 @@ flo_ceil(mrb_state *mrb, mrb_value num)
*/ */
static mrb_value static mrb_value
flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num) flo_round(mrb_state *mrb, mrb_value num)
{ {
mrb_value nd; double number, f;
mrb_float number, f;
int ndigits = 0, i; int ndigits = 0, i;
mrb_value *argv;
int argc;
mrb_get_args(mrb, "*", &argv, &argc);
if (argc == 1) { mrb_get_args(mrb, "|i", &ndigits);
nd = argv[0]; number = mrb_float(num);
ndigits = mrb_fixnum(nd);
}
number = mrb_float(num);
f = 1.0; f = 1.0;
i = abs(ndigits); i = abs(ndigits);
while (--i >= 0) while (--i >= 0)
...@@ -535,7 +531,7 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num) ...@@ -535,7 +531,7 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
if (ndigits < 0) number = 0; if (ndigits < 0) number = 0;
} }
else { else {
mrb_float d; double d;
if (ndigits < 0) number /= f; if (ndigits < 0) number /= f;
else number *= f; else number *= f;
...@@ -554,6 +550,11 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num) ...@@ -554,6 +550,11 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
else number /= f; else number /= f;
} }
{
mrb_value ff = mrb_float_value(number);
printf("%f.round(%d) = %f\n", mrb_float(num), ndigits, mrb_float(ff));
}
if (ndigits > 0) return mrb_float_value(number); if (ndigits > 0) return mrb_float_value(number);
return mrb_fixnum_value((mrb_int)number); return mrb_fixnum_value((mrb_int)number);
} }
......
...@@ -26,11 +26,11 @@ assert('Float#-', '15.2.9.3.2') do ...@@ -26,11 +26,11 @@ assert('Float#-', '15.2.9.3.2') do
end end
assert('Float#*', '15.2.9.3.3') do assert('Float#*', '15.2.9.3.3') do
a = 3.123456789 * 3.123456789 a = 3.125 * 3.125
b = 3.123456789 * 1 b = 3.125 * 1
check_float(a, 9.75598231275019) and check_float(a, 9.765625) and
check_float(b, 3.123456789) check_float(b, 3.125)
end end
assert('Float#/', '15.2.9.3.4') do assert('Float#/', '15.2.9.3.4') do
...@@ -42,19 +42,19 @@ assert('Float#/', '15.2.9.3.4') do ...@@ -42,19 +42,19 @@ assert('Float#/', '15.2.9.3.4') do
end end
assert('Float#%', '15.2.9.3.5') do assert('Float#%', '15.2.9.3.5') do
a = 3.123456789 % 3.123456789 a = 3.125 % 3.125
b = 3.123456789 % 1 b = 3.125 % 1
check_float(a, 0.0) and check_float(a, 0.0) and
check_float(b, 0.123456789) check_float(b, 0.125)
end end
assert('Float#<=>', '15.2.9.3.6') do assert('Float#<=>', '15.2.9.3.6') do
a = 3.123456789 <=> 3.123456788 a = 3.125 <=> 3.123
b = 3.123456789 <=> 3.123456789 b = 3.125 <=> 3.125
c = 3.123456789 <=> 3.123456790 c = 3.125 <=> 3.126
a2 = 3.123456789 <=> 3 a2 = 3.125 <=> 3
c2 = 3.123456789 <=> 4 c2 = 3.125 <=> 4
a == 1 and b == 0 and c == -1 and a == 1 and b == 0 and c == -1 and
a2 == 1 and c2 == -1 a2 == 1 and c2 == -1
...@@ -96,16 +96,16 @@ end ...@@ -96,16 +96,16 @@ end
assert('Float#round', '15.2.9.3.12') do assert('Float#round', '15.2.9.3.12') do
a = 3.123456789.round a = 3.123456789.round
b = 3.5.round b = 3.5.round
c = 3.499999999.round c = 3.4999.round
d = (-3.123456789).round d = (-3.123456789).round
e = (-3.5).round e = (-3.5).round
f = 12345.67.round(-1) f = 12345.67.round(-1)
g = 3.123456789.round(0) g = 3.423456789.round(0)
h = 3.123456789.round(1) h = 3.423456789.round(1)
i = 3.123456789.round(4) i = 3.423456789.round(3)
a == 3 and b == 4 and c == 3 and d == -3 and e == -4 and a == 3 and b == 4 and c == 3 and d == -3 and e == -4 and
f == 12350 and g == 3 and h == 3.1 and i == 3.1235 f == 12350 and g == 3 and h == 3.4 and i == 3.423
end end
assert('Float#to_f', '15.2.9.3.13') do assert('Float#to_f', '15.2.9.3.13') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment