From 8b32a1de29b09e4bbd9671db7172dac245611105 Mon Sep 17 00:00:00 2001 From: akr Date: Sat, 29 Aug 2009 19:06:29 +0000 Subject: * timev.h (TIME_SCALE): defined as 1000000000. (struct vtm): subsec is replaced by subsecx. subsec * TIME_SCALE == subsecx. * time.c: avoid rational in most cases. (struct time_object): timev is replaced by timexv. timev * TIME_SCALE == timexv. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24707 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++ time.c | 309 +++++++++++++++++++++++++++++++++----------------------------- timev.h | 4 +- 3 files changed, 177 insertions(+), 146 deletions(-) diff --git a/ChangeLog b/ChangeLog index 808c4e7d6a..33848903a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sun Aug 30 03:59:43 2009 Tanaka Akira + + * timev.h (TIME_SCALE): defined as 1000000000. + (struct vtm): subsec is replaced by subsecx. + subsec * TIME_SCALE == subsecx. + + * time.c: avoid rational in most cases. + (struct time_object): timev is replaced by timexv. + timev * TIME_SCALE == timexv. + Sun Aug 30 03:17:25 2009 Tanaka Akira * time.c (init_leap_second_info): use TIMET_MAX. diff --git a/time.c b/time.c index 599abe2b2e..e67a7bc5f7 100644 --- a/time.c +++ b/time.c @@ -66,7 +66,7 @@ static int tmcmp(struct tm *a, struct tm *b); static int vtmcmp(struct vtm *a, struct vtm *b); static const char *find_time_t(struct tm *tptr, int utc_p, time_t *tp); -static struct vtm *localtimev(VALUE timev, struct vtm *result); +static struct vtm *localtimexv(VALUE timexv, struct vtm *result); static int leap_year_p(long y); #define leap_year_v_p(y) leap_year_p(NUM2LONG(mod(v, INT2FIX(400)))) @@ -133,6 +133,8 @@ quo(VALUE x, VALUE y) return ret; } +#define mulquo(x,y,z) ((y == z) ? x : quo(mul(x,y),z)) + static void divmodv(VALUE n, VALUE d, VALUE *q, VALUE *r) { @@ -180,6 +182,18 @@ num_exact(VALUE v) return v; } +static VALUE +rb_time_magnify(VALUE v) +{ + return mul(v, INT2FIX(TIME_SCALE)); +} + +static VALUE +rb_time_unmagnify(VALUE v) +{ + return quo(v, INT2FIX(TIME_SCALE)); +} + static const int common_year_yday_offset[] = { -1, -1 + 31, @@ -219,7 +233,7 @@ static const int leap_year_days_in_month[] = { }; static VALUE -timegmv_noleapsecond(struct vtm *vtm) +timegmxv_noleapsecond(struct vtm *vtm) { VALUE year1900; VALUE q400, r400; @@ -255,7 +269,7 @@ timegmv_noleapsecond(struct vtm *vtm) ret = add(ret, mul(LONG2NUM(days_in400), INT2FIX(86400))); ret = add(ret, mul(q400, INT2FIX(97*86400))); ret = add(ret, mul(year1900, INT2FIX(365*86400))); - ret = add(ret, vtm->subsec); + ret = add(rb_time_magnify(ret), vtm->subsecx); return ret; } @@ -282,16 +296,17 @@ zone_str(const char *s) } static void -gmtimev_noleapsecond(VALUE timev, struct vtm *vtm) +gmtimexv_noleapsecond(VALUE timexv, struct vtm *vtm) { VALUE v; int i, n, x, y; const int *yday_offset; int wday; + VALUE timev; vtm->isdst = 0; - divmodv(timev, INT2FIX(1), &timev, &vtm->subsec); + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &vtm->subsecx); divmodv(timev, INT2FIX(86400), &timev, &v); wday = NUM2INT(mod(timev, INT2FIX(7))); @@ -521,7 +536,7 @@ init_leap_second_info() time_t now; struct tm *tm, result; struct vtm vtm; - VALUE timev; + VALUE timexv; now = time(NULL); gmtime(&now); tm = gmtime_with_leapsecond(&now, &result); @@ -541,19 +556,19 @@ init_leap_second_info() vtm.hour = result.tm_hour; vtm.min = result.tm_min; vtm.sec = result.tm_sec; - vtm.subsec = INT2FIX(0); + vtm.subsecx = INT2FIX(0); vtm.utc_offset = INT2FIX(0); - timev = timegmv_noleapsecond(&vtm); + timexv = timegmxv_noleapsecond(&vtm); - number_of_leap_seconds_known = NUM2INT(sub(TIMET2NUM(known_leap_seconds_limit), timev)); + number_of_leap_seconds_known = NUM2INT(sub(TIMET2NUM(known_leap_seconds_limit), rb_time_unmagnify(timexv))); } } static VALUE -timegmv(struct vtm *vtm) +timegmxv(struct vtm *vtm) { - VALUE timev; + VALUE timexv; struct tm tm; time_t t; const char *errmsg; @@ -561,14 +576,14 @@ timegmv(struct vtm *vtm) /* The first leap second is 1972-06-30 23:59:60 UTC. * No leap seconds before. */ if (RTEST(gt(INT2FIX(1972), vtm->year))) - return timegmv_noleapsecond(vtm); + return timegmxv_noleapsecond(vtm); init_leap_second_info(); - timev = timegmv_noleapsecond(vtm); + timexv = timegmxv_noleapsecond(vtm); - if (RTEST(lt(TIMET2NUM(known_leap_seconds_limit), timev))) { - return add(timev, INT2NUM(number_of_leap_seconds_known)); + if (RTEST(lt(rb_time_magnify(TIMET2NUM(known_leap_seconds_limit)), timexv))) { + return add(timexv, rb_time_magnify(INT2NUM(number_of_leap_seconds_known))); } tm.tm_year = NUM2LONG(vtm->year) - 1900; @@ -582,30 +597,31 @@ timegmv(struct vtm *vtm) errmsg = find_time_t(&tm, 1, &t); if (errmsg) rb_raise(rb_eArgError, "%s", errmsg); - return add(TIMET2NUM(t), vtm->subsec); + return add(rb_time_magnify(TIMET2NUM(t)), vtm->subsecx); } static struct vtm * -gmtimev(VALUE timev, struct vtm *result) +gmtimexv(VALUE timexv, struct vtm *result) { time_t t; struct tm tm; - VALUE subsec; + VALUE subsecx; + VALUE timev; - if (RTEST(lt(timev, INT2FIX(0)))) { - gmtimev_noleapsecond(timev, result); + if (RTEST(lt(timexv, INT2FIX(0)))) { + gmtimexv_noleapsecond(timexv, result); return result; } init_leap_second_info(); - if (RTEST(lt(LONG2NUM(known_leap_seconds_limit), timev))) { - timev = sub(timev, INT2NUM(number_of_leap_seconds_known)); - gmtimev_noleapsecond(timev, result); + if (RTEST(lt(rb_time_magnify(LONG2NUM(known_leap_seconds_limit)), timexv))) { + timexv = sub(timexv, rb_time_magnify(INT2NUM(number_of_leap_seconds_known))); + gmtimexv_noleapsecond(timexv, result); return result; } - divmodv(timev, INT2FIX(1), &timev, &subsec); + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx); t = NUM2TIMET(timev); if (!gmtime_with_leapsecond(&t, &tm)) @@ -617,7 +633,7 @@ gmtimev(VALUE timev, struct vtm *result) result->hour = tm.tm_hour; result->min = tm.tm_min; result->sec = tm.tm_sec; - result->subsec = subsec; + result->subsecx = subsecx; result->utc_offset = INT2FIX(0); result->wday = tm.tm_wday; result->yday = tm.tm_yday+1; @@ -760,7 +776,7 @@ guess_local_offset(struct vtm *vtm_utc) else vtm2.year = INT2FIX(compat_common_month_table[vtm_utc->mon-1][wday]); - timev = timegmv(&vtm2); + timev = rb_time_unmagnify(timegmxv(&vtm2)); t = NUM2TIMET(timev); if (localtime_with_gmtoff(&t, &tm, &gmtoff)) return LONG2FIX(gmtoff); @@ -796,12 +812,12 @@ small_vtm_sub(struct vtm *vtm1, struct vtm *vtm2) } static VALUE -timelocalv(struct vtm *vtm) +timelocalxv(struct vtm *vtm) { time_t t; struct tm tm; VALUE v; - VALUE timev1, timev2; + VALUE timexv1, timexv2; struct vtm vtm1, vtm2; int n; @@ -827,54 +843,54 @@ timelocalv(struct vtm *vtm) if (find_time_t(&tm, 0, &t)) goto no_localtime; - return add(TIMET2NUM(t), vtm->subsec); + return add(rb_time_magnify(TIMET2NUM(t)), vtm->subsecx); no_localtime: - timev1 = timegmv(vtm); + timexv1 = timegmxv(vtm); - if (!localtimev(timev1, &vtm1)) - rb_raise(rb_eArgError, "localtimev error"); + if (!localtimexv(timexv1, &vtm1)) + rb_raise(rb_eArgError, "localtimexv error"); n = vtmcmp(vtm, &vtm1); if (n == 0) { - timev1 = sub(timev1, INT2FIX(12*3600)); - if (!localtimev(timev1, &vtm1)) - rb_raise(rb_eArgError, "localtimev error"); + timexv1 = sub(timexv1, rb_time_magnify(INT2FIX(12*3600))); + if (!localtimexv(timexv1, &vtm1)) + rb_raise(rb_eArgError, "localtimexv error"); n = 1; } if (n < 0) { - timev2 = timev1; + timexv2 = timexv1; vtm2 = vtm1; - timev1 = sub(timev1, INT2FIX(24*3600)); - if (!localtimev(timev1, &vtm1)) - rb_raise(rb_eArgError, "localtimev error"); + timexv1 = sub(timexv1, rb_time_magnify(INT2FIX(24*3600))); + if (!localtimexv(timexv1, &vtm1)) + rb_raise(rb_eArgError, "localtimexv error"); } else { - timev2 = add(timev1, INT2FIX(24*3600)); - if (!localtimev(timev2, &vtm2)) - rb_raise(rb_eArgError, "localtimev error"); + timexv2 = add(timexv1, rb_time_magnify(INT2FIX(24*3600))); + if (!localtimexv(timexv2, &vtm2)) + rb_raise(rb_eArgError, "localtimexv error"); } - timev1 = add(timev1, small_vtm_sub(vtm, &vtm1)); - timev2 = add(timev2, small_vtm_sub(vtm, &vtm2)); + timexv1 = add(timexv1, rb_time_magnify(small_vtm_sub(vtm, &vtm1))); + timexv2 = add(timexv2, rb_time_magnify(small_vtm_sub(vtm, &vtm2))); - if (eq(timev1, timev2)) - return timev1; + if (eq(timexv1, timexv2)) + return timexv1; - if (!localtimev(timev1, &vtm1)) - rb_raise(rb_eArgError, "localtimev error"); + if (!localtimexv(timexv1, &vtm1)) + rb_raise(rb_eArgError, "localtimexv error"); if (vtm->hour != vtm1.hour || vtm->min != vtm1.min || vtm->sec != vtm1.sec) - return timev2; + return timexv2; - if (!localtimev(timev2, &vtm2)) - rb_raise(rb_eArgError, "localtimev error"); + if (!localtimexv(timexv2, &vtm2)) + rb_raise(rb_eArgError, "localtimexv error"); if (vtm->hour != vtm2.hour || vtm->min != vtm2.min || vtm->sec != vtm2.sec) - return timev1; + return timexv1; if (vtm->isdst) - return lt(vtm1.utc_offset, vtm2.utc_offset) ? timev2 : timev1; + return lt(vtm1.utc_offset, vtm2.utc_offset) ? timexv2 : timexv1; else - return lt(vtm1.utc_offset, vtm2.utc_offset) ? timev1 : timev2; + return lt(vtm1.utc_offset, vtm2.utc_offset) ? timexv1 : timexv2; } static struct tm * @@ -913,10 +929,10 @@ localtime_with_gmtoff(const time_t *t, struct tm *result, long *gmtoff) } static struct vtm * -localtimev(VALUE timev, struct vtm *result) +localtimexv(VALUE timexv, struct vtm *result) { - VALUE subsec, offset; - divmodv(timev, INT2FIX(1), &timev, &subsec); + VALUE timev, subsecx, offset; + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx); if (le(TIMET2NUM(TIMET_MIN), timev) && le(timev, TIMET2NUM(TIMET_MAX))) { @@ -932,7 +948,7 @@ localtimev(VALUE timev, struct vtm *result) result->hour = tm.tm_hour; result->min = tm.tm_min; result->sec = tm.tm_sec; - result->subsec = subsec; + result->subsecx = subsecx; result->wday = tm.tm_wday; result->yday = tm.tm_yday+1; result->isdst = tm.tm_isdst; @@ -954,12 +970,12 @@ localtimev(VALUE timev, struct vtm *result) } } - if (!gmtimev(timev, result)) + if (!gmtimexv(timexv, result)) return NULL; offset = guess_local_offset(result); - if (!gmtimev(add(timev, offset), result)) + if (!gmtimexv(add(timexv, rb_time_magnify(offset)), result)) return NULL; result->utc_offset = offset; @@ -968,7 +984,7 @@ localtimev(VALUE timev, struct vtm *result) } struct time_object { - VALUE timev; + VALUE timexv; struct vtm vtm; int gmt; int tm_got; @@ -1004,9 +1020,9 @@ time_mark(void *ptr) { struct time_object *tobj = ptr; if (!tobj) return; - rb_gc_mark(tobj->timev); + rb_gc_mark(tobj->timexv); rb_gc_mark(tobj->vtm.year); - rb_gc_mark(tobj->vtm.subsec); + rb_gc_mark(tobj->vtm.subsecx); rb_gc_mark(tobj->vtm.utc_offset); } @@ -1024,7 +1040,7 @@ time_s_alloc(VALUE klass) obj = Data_Make_Struct(klass, struct time_object, time_mark, time_free, tobj); tobj->tm_got=0; - tobj->timev = INT2FIX(0); + tobj->timexv = INT2FIX(0); return obj; } @@ -1038,27 +1054,27 @@ time_modify(VALUE time) } static VALUE -timespec2timev(struct timespec *ts) +timespec2timexv(struct timespec *ts) { - VALUE timev; + VALUE timexv; - timev = TIMET2NUM(ts->tv_sec); + timexv = rb_time_magnify(TIMET2NUM(ts->tv_sec)); if (ts->tv_nsec) - timev = add(timev, quo(LONG2NUM(ts->tv_nsec), INT2FIX(1000000000))); - return timev; + timexv = add(timexv, mulquo(LONG2NUM(ts->tv_nsec), INT2FIX(TIME_SCALE), INT2FIX(1000000000))); + return timexv; } static struct timespec -timev2timespec(VALUE timev) +timexv2timespec(VALUE timexv) { - VALUE subsec; + VALUE timev, subsecx; struct timespec ts; - divmodv(timev, INT2FIX(1), &timev, &subsec); + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx); if (lt(timev, TIMET2NUM(TIMET_MIN)) || lt(TIMET2NUM(TIMET_MAX), timev)) rb_raise(rb_eArgError, "time out of system range"); ts.tv_sec = NUM2TIMET(timev); - ts.tv_nsec = NUM2LONG(mul(subsec, INT2FIX(1000000000))); + ts.tv_nsec = NUM2LONG(mulquo(subsecx, INT2FIX(1000000000), INT2FIX(TIME_SCALE))); return ts; } @@ -1078,7 +1094,7 @@ time_init_0(VALUE time) time_modify(time); GetTimeval(time, tobj); tobj->tm_got=0; - tobj->timev = INT2FIX(0); + tobj->timexv = INT2FIX(0); #ifdef HAVE_CLOCK_GETTIME if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { rb_sys_fail("clock_gettime"); @@ -1093,7 +1109,7 @@ time_init_0(VALUE time) ts.tv_nsec = tv.tv_usec * 1000; } #endif - tobj->timev = timespec2timev(&ts); + tobj->timexv = timespec2timexv(&ts); return time; } @@ -1148,13 +1164,13 @@ vtm_add_offset(struct vtm *vtm, VALUE off) day = 0; if (!rb_equal(subsec, INT2FIX(0))) { - vtm->subsec = add(vtm->subsec, subsec); - if (lt(vtm->subsec, INT2FIX(0))) { - vtm->subsec = add(vtm->subsec, INT2FIX(1)); + vtm->subsecx = add(vtm->subsecx, rb_time_magnify(subsec)); + if (lt(vtm->subsecx, INT2FIX(0))) { + vtm->subsecx = add(vtm->subsecx, INT2FIX(TIME_SCALE)); sec -= 1; } - if (le(INT2FIX(1), vtm->subsec)) { - vtm->subsec = sub(vtm->subsec, INT2FIX(1)); + if (le(INT2FIX(TIME_SCALE), vtm->subsecx)) { + vtm->subsecx = sub(vtm->subsecx, INT2FIX(TIME_SCALE)); sec += 1; } goto not_zero_sec; @@ -1293,13 +1309,13 @@ time_init_1(int argc, VALUE *argv, VALUE time) vtm.min = NIL_P(v[4]) ? 0 : obj2long(v[4]); vtm.sec = 0; - vtm.subsec = INT2FIX(0); + vtm.subsecx = INT2FIX(0); if (!NIL_P(v[5])) { VALUE sec = num_exact(v[5]); VALUE subsec; divmodv(sec, INT2FIX(1), &sec, &subsec); vtm.sec = NUM2INT(sec); - vtm.subsec = subsec; + vtm.subsecx = rb_time_magnify(subsec); } vtm.isdst = -1; @@ -1319,17 +1335,17 @@ time_init_1(int argc, VALUE *argv, VALUE time) time_modify(time); GetTimeval(time, tobj); tobj->tm_got=0; - tobj->timev = INT2FIX(0); + tobj->timexv = INT2FIX(0); if (!NIL_P(vtm.utc_offset)) { VALUE off = vtm.utc_offset; vtm_add_offset(&vtm, neg(off)); vtm.utc_offset = Qnil; - tobj->timev = timegmv(&vtm); + tobj->timexv = timegmxv(&vtm); return time_set_utc_offset(time, off); } else { - tobj->timev = timelocalv(&vtm); + tobj->timexv = timelocalxv(&vtm); return time_localtime(time); } } @@ -1409,23 +1425,23 @@ time_overflow_p(time_t *secp, long *nsecp) *nsecp = nsec; } -static VALUE nsec2timev(time_t sec, long nsec) +static VALUE nsec2timexv(time_t sec, long nsec) { struct timespec ts; time_overflow_p(&sec, &nsec); ts.tv_sec = sec; ts.tv_nsec = nsec; - return timespec2timev(&ts); + return timespec2timexv(&ts); } static VALUE -time_new_internal(VALUE klass, VALUE timev) +time_new_internal(VALUE klass, VALUE timexv) { VALUE time = time_s_alloc(klass); struct time_object *tobj; GetTimeval(time, tobj); - tobj->timev = num_exact(timev); + tobj->timexv = num_exact(timexv); return time; } @@ -1433,19 +1449,19 @@ time_new_internal(VALUE klass, VALUE timev) VALUE rb_time_new(time_t sec, long usec) { - return time_new_internal(rb_cTime, nsec2timev(sec, usec * 1000)); + return time_new_internal(rb_cTime, nsec2timexv(sec, usec * 1000)); } VALUE rb_time_nano_new(time_t sec, long nsec) { - return time_new_internal(rb_cTime, nsec2timev(sec, nsec)); + return time_new_internal(rb_cTime, nsec2timexv(sec, nsec)); } VALUE rb_time_num_new(VALUE timev, VALUE off) { - VALUE time = time_new_internal(rb_cTime, timev); + VALUE time = time_new_internal(rb_cTime, rb_time_magnify(timev)); if (!NIL_P(off)) { off = utc_offset_arg(off); @@ -1458,13 +1474,13 @@ rb_time_num_new(VALUE timev, VALUE off) } static VALUE -time_new_timev(VALUE klass, VALUE timev) +time_new_timexv(VALUE klass, VALUE timexv) { VALUE time = time_s_alloc(klass); struct time_object *tobj; GetTimeval(time, tobj); - tobj->timev = timev; + tobj->timexv = timexv; return time; } @@ -1568,7 +1584,7 @@ rb_time_timeval(VALUE time) if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) { GetTimeval(time, tobj); - ts = timev2timespec(tobj->timev); + ts = timexv2timespec(tobj->timexv); t.tv_sec = (TYPEOF_TIMEVAL_TV_SEC)ts.tv_sec; t.tv_usec = (TYPEOF_TIMEVAL_TV_USEC)(ts.tv_nsec / 1000); return t; @@ -1584,7 +1600,7 @@ rb_time_timespec(VALUE time) if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) { GetTimeval(time, tobj); - t = timev2timespec(tobj->timev); + t = timexv2timespec(tobj->timexv); return t; } return time_timespec(time, Qfalse); @@ -1629,24 +1645,24 @@ time_s_now(VALUE klass) static VALUE time_s_at(int argc, VALUE *argv, VALUE klass) { - VALUE time, t, timev; + VALUE time, t, timexv; if (rb_scan_args(argc, argv, "11", &time, &t) == 2) { time = num_exact(time); t = num_exact(t); - timev = add(time, quo(t, INT2FIX(1000000))); - t = time_new_timev(klass, timev); + timexv = add(rb_time_magnify(time), mulquo(t, INT2FIX(TIME_SCALE), INT2FIX(1000000))); + t = time_new_timexv(klass, timexv); } else if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) { struct time_object *tobj, *tobj2; GetTimeval(time, tobj); - t = time_new_timev(klass, tobj->timev); + t = time_new_timexv(klass, tobj->timexv); GetTimeval(t, tobj2); TIME_COPY_GMT(tobj2, tobj); } else { - timev = num_exact(time); - t = time_new_timev(klass, timev); + timexv = rb_time_magnify(num_exact(time)); + t = time_new_timexv(klass, timexv); } return t; @@ -1681,26 +1697,29 @@ obj2vint(VALUE obj) } static long -obj2subsec(VALUE obj, VALUE *subsec) +obj2subsecx(VALUE obj, VALUE *subsecx) { + VALUE subsec; + if (TYPE(obj) == T_STRING) { obj = rb_str_to_inum(obj, 10, Qfalse); - *subsec = INT2FIX(0); + *subsecx = INT2FIX(0); return NUM2LONG(obj); } - divmodv(num_exact(obj), INT2FIX(1), &obj, subsec); + divmodv(num_exact(obj), INT2FIX(1), &obj, &subsec); + *subsecx = rb_time_magnify(subsec); return NUM2LONG(obj); } static long -usec2subsec(VALUE obj) +usec2subsecx(VALUE obj) { if (TYPE(obj) == T_STRING) { obj = rb_str_to_inum(obj, 10, Qfalse); } - return quo(num_exact(obj), INT2FIX(1000000)); + return mulquo(num_exact(obj), INT2FIX(TIME_SCALE), INT2FIX(1000000)); } static int @@ -1748,7 +1767,7 @@ validate_vtm(struct vtm *vtm) || (vtm->hour == 24 && (vtm->min > 0 || vtm->sec > 0)) || vtm->min < 0 || vtm->min > 59 || vtm->sec < 0 || vtm->sec > 60 - || lt(vtm->subsec, INT2FIX(0)) || ge(vtm->subsec, INT2FIX(1)) + || lt(vtm->subsecx, INT2FIX(0)) || ge(vtm->subsecx, INT2FIX(TIME_SCALE)) || (!NIL_P(vtm->utc_offset) && (validate_utc_offset(vtm->utc_offset), 0))) rb_raise(rb_eArgError, "argument out of range"); } @@ -1764,7 +1783,7 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm) vtm->hour = 0; vtm->min = 0; vtm->sec = 0; - vtm->subsec = INT2FIX(0); + vtm->subsecx = INT2FIX(0); vtm->utc_offset = Qnil; vtm->wday = 0; vtm->yday = 0; @@ -1811,11 +1830,11 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm) if (!NIL_P(v[6]) && argc == 7) { vtm->sec = NIL_P(v[5])?0:obj2long(v[5]); - vtm->subsec = usec2subsec(v[6]); + vtm->subsecx = usec2subsecx(v[6]); } else { /* when argc == 8, v[6] is timezone, but ignored */ - vtm->sec = NIL_P(v[5])?0:obj2subsec(v[5], &vtm->subsec); + vtm->sec = NIL_P(v[5])?0:obj2subsecx(v[5], &vtm->subsecx); } validate_vtm(vtm); @@ -2139,8 +2158,8 @@ vtmcmp(struct vtm *a, struct vtm *b) return a->min < b->min ? -1 : 1; else if (a->sec != b->sec) return a->sec < b->sec ? -1 : 1; - else if (ne(a->subsec, b->subsec)) - return lt(a->subsec, b->subsec) ? -1 : 1; + else if (ne(a->subsecx, b->subsecx)) + return lt(a->subsecx, b->subsecx) ? -1 : 1; else return 0; } @@ -2172,9 +2191,9 @@ time_utc_or_local(int argc, VALUE *argv, int utc_p, VALUE klass) time_arg(argc, argv, &vtm); if (utc_p) - time = time_new_timev(klass, timegmv(&vtm)); + time = time_new_timexv(klass, timegmxv(&vtm)); else - time = time_new_timev(klass, timelocalv(&vtm)); + time = time_new_timexv(klass, timelocalxv(&vtm)); if (utc_p) return time_gmtime(time); return time_localtime(time); } @@ -2267,7 +2286,7 @@ time_to_i(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return div(tobj->timev, INT2FIX(1)); + return div(tobj->timexv, INT2FIX(TIME_SCALE)); } /* @@ -2291,7 +2310,7 @@ time_to_f(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return rb_Float(tobj->timev); + return rb_Float(rb_time_unmagnify(tobj->timexv)); } /* @@ -2315,7 +2334,7 @@ time_to_r(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return tobj->timev; + return rb_time_unmagnify(tobj->timexv); } /* @@ -2336,7 +2355,7 @@ time_usec(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return rb_to_int(mul(mod(tobj->timev, INT2FIX(1)), INT2FIX(1000000))); + return rb_to_int(mulquo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(1000000), INT2FIX(TIME_SCALE))); } /* @@ -2362,7 +2381,7 @@ time_nsec(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return rb_to_int(mul(mod(tobj->timev, INT2FIX(1)), INT2FIX(1000000000))); + return rb_to_int(mulquo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(1000000000), INT2FIX(TIME_SCALE))); } /* @@ -2389,7 +2408,7 @@ time_subsec(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return mod(tobj->timev, INT2FIX(1)); + return quo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(TIME_SCALE)); } /* @@ -2421,7 +2440,7 @@ time_cmp(VALUE time1, VALUE time2) GetTimeval(time1, tobj1); if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) { GetTimeval(time2, tobj2); - n = rb_cmpint(cmp(tobj1->timev, tobj2->timev), tobj1->timev, tobj2->timev); + n = rb_cmpint(cmp(tobj1->timexv, tobj2->timexv), tobj1->timexv, tobj2->timexv); } else { VALUE cmp; @@ -2453,7 +2472,7 @@ time_eql(VALUE time1, VALUE time2) GetTimeval(time1, tobj1); if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) { GetTimeval(time2, tobj2); - return rb_equal(tobj1->timev, tobj2->timev); + return rb_equal(tobj1->timexv, tobj2->timexv); } return Qfalse; } @@ -2500,7 +2519,7 @@ time_hash(VALUE time) struct time_object *tobj; GetTimeval(time, tobj); - return rb_hash(tobj->timev); + return rb_hash(tobj->timexv); } /* :nodoc: */ @@ -2544,7 +2563,7 @@ time_localtime(VALUE time) time_modify(time); } - if (!localtimev(tobj->timev, &vtm)) + if (!localtimexv(tobj->timexv, &vtm)) rb_raise(rb_eArgError, "localtime error"); tobj->vtm = vtm; @@ -2623,7 +2642,7 @@ time_gmtime(VALUE time) time_modify(time); } - if (!gmtimev(tobj->timev, &vtm)) + if (!gmtimexv(tobj->timexv, &vtm)) rb_raise(rb_eArgError, "gmtime error"); tobj->vtm = vtm; @@ -2653,7 +2672,7 @@ time_fixoff(VALUE time) else off = INT2FIX(0); - if (!gmtimev(tobj->timev, &vtm)) + if (!gmtimexv(tobj->timexv, &vtm)) rb_raise(rb_eArgError, "gmtime error"); tobj->vtm = vtm; @@ -2788,9 +2807,9 @@ time_add(struct time_object *tobj, VALUE offset, int sign) VALUE result; offset = num_exact(offset); if (sign < 0) - result = time_new_timev(rb_cTime, sub(tobj->timev, offset)); + result = time_new_timexv(rb_cTime, sub(tobj->timexv, rb_time_magnify(offset))); else - result = time_new_timev(rb_cTime, add(tobj->timev, offset)); + result = time_new_timexv(rb_cTime, add(tobj->timexv, rb_time_magnify(offset))); if (TIME_UTC_P(tobj)) { GetTimeval(result, tobj); TIME_SET_UTC(tobj); @@ -2846,7 +2865,7 @@ time_minus(VALUE time1, VALUE time2) struct time_object *tobj2; GetTimeval(time2, tobj2); - return rb_Float(sub(tobj->timev, tobj2->timev)); + return rb_Float(rb_time_unmagnify(sub(tobj->timexv, tobj2->timexv))); } return time_add(tobj, time2, -1); } @@ -2868,7 +2887,7 @@ time_succ(VALUE time) struct time_object *tobj2; GetTimeval(time, tobj); - time = time_new_timev(rb_cTime, add(tobj->timev, INT2FIX(1))); + time = time_new_timexv(rb_cTime, add(tobj->timexv, INT2FIX(TIME_SCALE))); GetTimeval(time, tobj2); TIME_COPY_GMT(tobj2, tobj); return time; @@ -3351,7 +3370,7 @@ strftimev(const char *fmt, VALUE time) GetTimeval(time, tobj); MAKE_TM(time, tobj); - len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, tobj->timev, TIME_UTC_P(tobj)); + len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj)); str = rb_str_new(buf, len); if (buf != buffer) xfree(buf); return str; @@ -3449,7 +3468,7 @@ time_strftime(VALUE time, VALUE format) str = rb_str_new(0, 0); while (p < pe) { - len = rb_strftime_alloc(&buf, p, &tobj->vtm, tobj->timev, TIME_UTC_P(tobj)); + len = rb_strftime_alloc(&buf, p, &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj)); rb_str_cat(str, buf, len); p += strlen(p); if (buf != buffer) { @@ -3463,7 +3482,7 @@ time_strftime(VALUE time, VALUE format) } else { len = rb_strftime_alloc(&buf, RSTRING_PTR(format), - &tobj->vtm, tobj->timev, TIME_UTC_P(tobj)); + &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj)); } str = rb_str_new(buf, len); if (buf != buffer) xfree(buf); @@ -3487,11 +3506,11 @@ time_mdump(VALUE time) struct vtm vtm; long year; long usec, nsec; - VALUE subsec, subnano, v; + VALUE subsecx, nano, subnano, v; GetTimeval(time, tobj); - gmtimev(tobj->timev, &vtm); + gmtimexv(tobj->timexv, &vtm); if (FIXNUM_P(vtm.year)) { year = FIX2LONG(vtm.year); @@ -3502,10 +3521,10 @@ time_mdump(VALUE time) rb_raise(rb_eArgError, "year too big to marshal"); } - subsec = vtm.subsec; + subsecx = vtm.subsecx; - subsec = mul(subsec, INT2FIX(1000000000)); - divmodv(subsec, INT2FIX(1), &v, &subnano); + nano = mulquo(subsecx, INT2FIX(1000000000), INT2FIX(TIME_SCALE)); + divmodv(nano, INT2FIX(1), &v, &subnano); nsec = FIX2LONG(v); usec = nsec / 1000; nsec = nsec % 1000; @@ -3589,7 +3608,7 @@ time_mload(VALUE time, VALUE str) struct vtm vtm; int i, gmt; long nsec; - VALUE timev, submicro, subnano; + VALUE timexv, submicro, subnano; time_modify(time); @@ -3622,7 +3641,7 @@ time_mload(VALUE time, VALUE str) sec = p; usec = s; nsec = usec * 1000; - timev = add(TIMET2NUM(sec), quo(LONG2FIX(usec), LONG2FIX(1000000))); + timexv = add(rb_time_magnify(TIMET2NUM(sec)), mulquo(LONG2FIX(usec), INT2FIX(TIME_SCALE), LONG2FIX(1000000))); } else { p &= ~(1UL<<31); @@ -3661,18 +3680,18 @@ time_mload(VALUE time, VALUE str) end_submicro: ; } - vtm.subsec = quo(LONG2FIX(nsec), LONG2FIX(1000000000)); + vtm.subsecx = mulquo(LONG2FIX(nsec), INT2FIX(TIME_SCALE), LONG2FIX(1000000000)); if (subnano != Qnil) { subnano = num_exact(subnano); - vtm.subsec = add(vtm.subsec, quo(subnano, LONG2FIX(1000000000))); + vtm.subsecx = add(vtm.subsecx, mulquo(subnano, INT2FIX(TIME_SCALE), LONG2FIX(1000000000))); } - timev = timegmv(&vtm); + timexv = timegmxv(&vtm); } GetTimeval(time, tobj); tobj->tm_got = 0; if (gmt) TIME_SET_UTC(tobj); - tobj->timev = timev; + tobj->timexv = timexv; return time; } diff --git a/timev.h b/timev.h index 6fa4f86415..631fcf3e1d 100644 --- a/timev.h +++ b/timev.h @@ -8,7 +8,7 @@ struct vtm { int hour; /* 0..23 */ int min; /* 0..59 */ int sec; /* 0..60 */ - VALUE subsec; /* 0 <= subsec < 1. possibly Rational. */ + VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */ VALUE utc_offset; /* -3600 as -01:00 for example. possibly Rational. */ int wday; /* 0:Sunday, 1:Monday, ..., 6:Saturday */ int yday; /* 1..366 */ @@ -16,4 +16,6 @@ struct vtm { const char *zone; /* "JST", "EST", "EDT", etc. */ }; +#define TIME_SCALE 1000000000 + #endif -- cgit v1.2.3