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 backwardscompatible, 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(f0.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(f0.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));
+}

/*
 callseq:

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);