Joel VanderWerf wrote:
Pat M. wrote:
I’m doing some math that results in floats with ~10 decimal places,
but I’d like to round them to 2 places. Is there a built in way of
doing this? Right now I’m doing format(“%0.2f”, the_float).to_f,
which seems to work fine but it seems like an ugly way of doing it.
…
This might be good place to use a C extension, if you really need it to
be fast.
Facets adds Numeric#round_at(d) and round_to(n).
http://facets.rubyforge.org/doc/api/classes/Float.html
Why not alter Ruby’s core Numeric#round to accept an extra parameter,
with
the same function as Facets’ round_at(d)? I’ve attached a patch
(untested)
below.
It seems to me it’s fully backwards-compatible, hardly slower, and not
at
all confusing. Round is a good name for this function, and it isn’t
incongruent with the existing function of that method.
Cheers,
Dave
Untested patch against 1.8.2:
— numeric.c~ Wed Mar 22 19:41:54 2006
+++ numeric.c Wed Mar 22 22:01:47 2006
@@ -1274,17 +1274,35 @@
flo_round(num)
VALUE num;
{
- return flo_round2(0, NULL, num);
+}
-
+static VALUE
+flo_round2(argc, argv, num)
- int argc;
- VALUE *argv;
- VALUE num;
+{
double f = RFLOAT(num)->value;
long val;
- int dp;
- double x;
- if (f > 0.0) f = floor(f+0.5);
- if (f < 0.0) f = ceil(f-0.5);
- if (argc) {
-
rb_scan_args(argc, argv, "01", &dp);
-
x = pow(10.0, (double)dp);
-
return rb_float_new((int)(num * x) / x);
- }
- else {
-
if (f > 0.0) f = floor(f+0.5);
-
if (f < 0.0) f = ceil(f-0.5);
- if (!FIXABLE(f)) {
-
return rb_dbl2big(f);
-
if (!FIXABLE(f)) {
-
return rb_dbl2big(f);
-
}
-
val = f;
-
return LONG2FIX(val);
}
- val = f;
- return LONG2FIX(val);
}
/*
@@ -1372,6 +1390,15 @@
return flo_round(rb_Float(num));
}
+static VALUE
+num_round2(argc, argv, num)
- int argc,
-
VALUE *argv,
- VALUE num;
+{
- return flo_round(argc, argv, rb_Float(num));
+}
-
/*
- call-seq:
-
num.truncate => integer
@@ -2799,7 +2826,7 @@
rb_define_method(rb_cNumeric, "floor", num_floor, 0);
rb_define_method(rb_cNumeric, "ceil", num_ceil, 0);
- rb_define_method(rb_cNumeric, “round”, num_round, 0);
- rb_define_method(rb_cNumeric, “round”, num_round2, -1);
rb_define_method(rb_cNumeric, “truncate”, num_truncate, 0);
rb_define_method(rb_cNumeric, “step”, num_step, -1);
@@ -2819,7 +2846,6 @@
rb_define_method(rb_cInteger, “to_int”, int_to_i, 0);
rb_define_method(rb_cInteger, “floor”, int_to_i, 0);
rb_define_method(rb_cInteger, “ceil”, int_to_i, 0);
-
rb_define_method(rb_cInteger, “round”, int_to_i, 0);
rb_define_method(rb_cInteger, “truncate”, int_to_i, 0);
rb_cFixnum = rb_define_class(“Fixnum”, rb_cInteger);
@@ -2913,7 +2939,7 @@
rb_define_method(rb_cFloat, “to_int”, flo_truncate, 0);
rb_define_method(rb_cFloat, “floor”, flo_floor, 0);
rb_define_method(rb_cFloat, “ceil”, flo_ceil, 0);
-
rb_define_method(rb_cFloat, “round”, flo_round, 0);
-
rb_define_method(rb_cFloat, “round”, flo_round2, -1);
rb_define_method(rb_cFloat, “truncate”, flo_truncate, 0);
rb_define_method(rb_cFloat, “nan?”, flo_is_nan_p, 0);