aboutsummaryrefslogtreecommitdiffstats
path: root/time.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-05-24 15:07:38 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-05-24 15:16:19 +0900
commit1a4080cb0ade6c700ce763d4290e5b56635d1bc8 (patch)
treefd3233089e8e505e6c1e6f38dbfe035c1d85b93d /time.c
parent54d5b599e850c08f92581645c56e4f5ccf20eb45 (diff)
downloadruby-1a4080cb0ade6c700ce763d4290e5b56635d1bc8.tar.gz
Hoisted out ndigits_denominator
* time.c (ndigits_denominator): calculate the denominator for digits.
Diffstat (limited to 'time.c')
-rw-r--r--time.c75
1 files changed, 24 insertions, 51 deletions
diff --git a/time.c b/time.c
index a7654b2465..99f6fe0998 100644
--- a/time.c
+++ b/time.c
@@ -4159,6 +4159,21 @@ rb_time_succ(VALUE time)
#define time_succ rb_time_succ
+static VALUE
+ndigits_denominator(VALUE ndigits)
+{
+ long nd = NUM2LONG(ndigits);
+
+ if (nd < 0) {
+ rb_raise(rb_eArgError, "negative ndigits given");
+ }
+ if (nd == 0) {
+ return INT2FIX(1);
+ }
+ return rb_rational_new(INT2FIX(1),
+ rb_int_positive_pow(10, (unsigned long)nd));
+}
+
/*
* call-seq:
* time.round([ndigits]) -> new_time
@@ -4193,31 +4208,17 @@ rb_time_succ(VALUE time)
static VALUE
time_round(int argc, VALUE *argv, VALUE time)
{
- VALUE ndigits, v, a, b, den;
- long nd;
+ VALUE ndigits, v, den;
struct time_object *tobj;
if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0]))
- ndigits = INT2FIX(0);
+ den = INT2FIX(1);
else
- ndigits = rb_to_int(ndigits);
-
- nd = NUM2LONG(ndigits);
- if (nd < 0)
- rb_raise(rb_eArgError, "negative ndigits given");
+ den = ndigits_denominator(ndigits);
GetTimeval(time, tobj);
v = w2v(rb_time_unmagnify(tobj->timew));
- a = INT2FIX(1);
- b = INT2FIX(10);
- while (0 < nd) {
- if (nd & 1)
- a = mulv(a, b);
- b = mulv(b, b);
- nd = nd >> 1;
- }
- den = quov(INT2FIX(1), a);
v = modv(v, den);
if (lt(v, quov(den, INT2FIX(2))))
return time_add(tobj, time, v, -1);
@@ -4257,31 +4258,17 @@ time_round(int argc, VALUE *argv, VALUE time)
static VALUE
time_floor(int argc, VALUE *argv, VALUE time)
{
- VALUE ndigits, v, a, b, den;
- long nd;
+ VALUE ndigits, v, den;
struct time_object *tobj;
if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0]))
- ndigits = INT2FIX(0);
+ den = INT2FIX(1);
else
- ndigits = rb_to_int(ndigits);
-
- nd = NUM2LONG(ndigits);
- if (nd < 0)
- rb_raise(rb_eArgError, "negative ndigits given");
+ den = ndigits_denominator(ndigits);
GetTimeval(time, tobj);
v = w2v(rb_time_unmagnify(tobj->timew));
- a = INT2FIX(1);
- b = INT2FIX(10);
- while (0 < nd) {
- if (nd & 1)
- a = mulv(a, b);
- b = mulv(b, b);
- nd = nd >> 1;
- }
- den = quov(INT2FIX(1), a);
v = modv(v, den);
return time_add(tobj, time, v, -1);
}
@@ -4318,31 +4305,17 @@ time_floor(int argc, VALUE *argv, VALUE time)
static VALUE
time_ceil(int argc, VALUE *argv, VALUE time)
{
- VALUE ndigits, v, a, b, den;
- long nd;
+ VALUE ndigits, v, den;
struct time_object *tobj;
if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0]))
- ndigits = INT2FIX(0);
+ den = INT2FIX(1);
else
- ndigits = rb_to_int(ndigits);
-
- nd = NUM2LONG(ndigits);
- if (nd < 0)
- rb_raise(rb_eArgError, "negative ndigits given");
+ den = ndigits_denominator(ndigits);
GetTimeval(time, tobj);
v = w2v(rb_time_unmagnify(tobj->timew));
- a = INT2FIX(1);
- b = INT2FIX(10);
- while (0 < nd) {
- if (nd & 1)
- a = mulv(a, b);
- b = mulv(b, b);
- nd = nd >> 1;
- }
- den = quov(INT2FIX(1), a);
v = modv(v, den);
return time_add(tobj, time, subv(den, v), 1);
}