diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | bignum.c | 71 | ||||
-rw-r--r-- | common.mk | 4 | ||||
-rw-r--r-- | include/ruby/util.h | 18 | ||||
-rw-r--r-- | marshal.c | 31 | ||||
-rw-r--r-- | numeric.c | 15 | ||||
-rw-r--r-- | util.c | 2 |
7 files changed, 87 insertions, 64 deletions
@@ -1,3 +1,13 @@ +Tue May 26 13:58:13 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * common.mk (bignum.o, numeric.o): depend on util.h. + + * bignum.c, marshal.c: fixed types. + + * numeric.c (infinite_value): use ruby_div0. + + * include/ruby/util.h (ruby_div0): moved from marshal.c. + Tue May 26 11:01:41 2009 TAKANO Mitsuhiro (takano32) <tak@no32.tk> * lib/mkmf.rb: use map! to replace strings in $objs array. @@ -10,6 +10,7 @@ **********************************************************************/ #include "ruby/ruby.h" +#include "ruby/util.h" #include <math.h> #include <float.h> @@ -28,9 +29,9 @@ VALUE rb_cBignum; #define BDIGITS(x) (RBIGNUM_DIGITS(x)) #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT) #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG) -#define DIGSPERLONG ((unsigned int)(SIZEOF_LONG/SIZEOF_BDIGITS)) +#define DIGSPERLONG (SIZEOF_LONG/SIZEOF_BDIGITS) #if HAVE_LONG_LONG -# define DIGSPERLL ((unsigned int)(SIZEOF_LONG_LONG/SIZEOF_BDIGITS)) +# define DIGSPERLL (SIZEOF_LONG_LONG/SIZEOF_BDIGITS) #endif #define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG) #define BIGDN(x) RSHIFT(x,BITSPERDIG) @@ -200,7 +201,7 @@ bigfixize(VALUE x) BDIGIT *ds = BDIGITS(x); if (len == 0) return INT2FIX(0); - if (len*SIZEOF_BDIGITS <= sizeof(long)) { + if ((size_t)(len*SIZEOF_BDIGITS) <= sizeof(long)) { long num = 0; #if 2*SIZEOF_BDIGITS > SIZEOF_LONG num = (long)ds[0]; @@ -532,7 +533,7 @@ rb_cstr_to_inum(const char *str, int base, int badcheck) } len *= strlen(str)*sizeof(char); - if (len <= (sizeof(long)*CHAR_BIT)) { + if ((size_t)len <= (sizeof(long)*CHAR_BIT)) { unsigned long val = STRTOUL(str, &end, base); if (str < end && *end == '_') goto bigparse; @@ -797,7 +798,8 @@ power_cache_get_power0(int base, int i) static VALUE power_cache_get_power(int base, long n1, long* m1) { - long i, j, m; + int i, m; + long j; VALUE t; if (n1 <= KARATSUBA_DIGITS) @@ -1197,20 +1199,27 @@ big2dbl(VALUE x) } dl = ds[i]; if (bits && (dl & (1UL << (bits %= BITSPERDIG)))) { - int carry = dl & ~(~0UL << bits); + int carry = dl & ~(~(BDIGIT)0 << bits); if (!carry) { while (i-- > 0) { if ((carry = ds[i]) != 0) break; } } if (carry) { - dl &= ~0UL << bits; - dl += 1UL << bits; + dl &= (BDIGIT)~0 << bits; + dl += (BDIGIT)1 << bits; if (!dl) d += 1; } } d = dl + BIGRAD*d; - if (lo) d = ldexp(d, lo * BITSPERDIG); + if (lo) { + if (lo > INT_MAX / BITSPERDIG) + d = HUGE_VAL; + else if (lo < INT_MIN / BITSPERDIG) + d = 0.0; + else + d = ldexp(d, (int)(lo * BITSPERDIG)); + } } } if (!RBIGNUM_SIGN(x)) d = -d; @@ -1477,7 +1486,7 @@ bigsub_int(VALUE x, long y0) for (i=0; i<xn; i++) { } RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x)); - zds[0] = -num; + zds[0] = (BDIGIT)-num; return bignorm(z); } zds[0] = BIGLO(num); @@ -1485,7 +1494,7 @@ bigsub_int(VALUE x, long y0) i = 1; #else num = 0; - for (i=0; i<sizeof(y)/sizeof(BDIGIT); i++) { + for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) { num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y); zds[i] = BIGLO(num); num = BIGDN(num); @@ -1535,7 +1544,7 @@ bigadd_int(VALUE x, long y) i = 1; #else num = 0; - for (i=0; i<sizeof(y)/sizeof(BDIGIT); i++) { + for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) { num += (BDIGIT_DBL)xds[i] + BIGLO(y); zds[i] = BIGLO(num); num = BIGDN(num); @@ -2363,12 +2372,13 @@ bdigbitsize(BDIGIT x) static VALUE big_lshift(VALUE, unsigned long); static VALUE big_rshift(VALUE, unsigned long); -static VALUE big_shift(VALUE x, int n) +static VALUE +big_shift(VALUE x, long n) { if (n < 0) - return big_lshift(x, (unsigned int)-n); + return big_lshift(x, (unsigned long)-n); else if (n > 0) - return big_rshift(x, (unsigned int)n); + return big_rshift(x, (unsigned long)n); return x; } @@ -2393,11 +2403,13 @@ rb_big_fdiv(VALUE x, VALUE y) if (isinf(dx)) { #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG) VALUE z; - int ex, ey; + long l, ex, ey; + int i; bigtrunc(x); - ex = (RBIGNUM_LEN(x) - 1) * BITSPERDIG; - ex += bdigbitsize(BDIGITS(x)[RBIGNUM_LEN(x) - 1]); + l = RBIGNUM_LEN(x) - 1; + ex = l * BITSPERDIG; + ex += bdigbitsize(BDIGITS(x)[l]); ex -= 2 * DBL_BIGDIG * BITSPERDIG; if (ex) x = big_shift(x, ex); @@ -2406,18 +2418,27 @@ rb_big_fdiv(VALUE x, VALUE y) y = rb_int2big(FIX2LONG(y)); case T_BIGNUM: { bigtrunc(y); - ey = (RBIGNUM_LEN(y) - 1) * BITSPERDIG; - ey += bdigbitsize(BDIGITS(y)[RBIGNUM_LEN(y) - 1]); + l = RBIGNUM_LEN(y) - 1; + ey = l * BITSPERDIG; + ey += bdigbitsize(BDIGITS(y)[l]); ey -= DBL_BIGDIG * BITSPERDIG; if (ey) y = big_shift(y, ey); bignum: bigdivrem(x, y, &z, 0); - return DBL2NUM(ldexp(big2dbl(z), ex - ey)); + l = ex - ey; +#if SIZEOF_LONG > SIZEOF_INT + { + /* Visual C++ can't be here */ + if (l > INT_MAX) return DBL2NUM(ruby_div0(1.0)); + if (l < INT_MIN) return DBL2NUM(0.0); + } +#endif + return DBL2NUM(ldexp(big2dbl(z), (int)l)); } case T_FLOAT: if (isnan(RFLOAT_VALUE(y))) return y; - y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &ey), DBL_MANT_DIG)); - ey -= DBL_MANT_DIG; + y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG)); + ey = i - DBL_MANT_DIG; goto bignum; } } @@ -2746,7 +2767,7 @@ big_lshift(VALUE x, unsigned long shift) { BDIGIT *xds, *zds; long s1 = shift/BITSPERDIG; - int s2 = shift%BITSPERDIG; + int s2 = (int)(shift%BITSPERDIG); VALUE z; BDIGIT_DBL num = 0; long len, i; @@ -2812,7 +2833,7 @@ big_rshift(VALUE x, unsigned long shift) { BDIGIT *xds, *zds; long s1 = shift/BITSPERDIG; - int s2 = shift%BITSPERDIG; + int s2 = (int)(shift%BITSPERDIG); VALUE z; BDIGIT_DBL num = 0; long i, j; @@ -486,7 +486,7 @@ VM_CORE_H_INCLUDES = {$(VPATH)}vm_core.h {$(VPATH)}vm_opts.h \ {$(VPATH)}node.h $(ID_H_INCLUDES) array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h -bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) +bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h class.$(OBJEXT): {$(VPATH)}class.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h compar.$(OBJEXT): {$(VPATH)}compar.c $(RUBY_H_INCLUDES) complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES) @@ -527,7 +527,7 @@ main.$(OBJEXT): {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}debug.h \ marshal.$(OBJEXT): {$(VPATH)}marshal.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \ $(ENCODING_H_INCLUDES) {$(VPATH)}util.h math.$(OBJEXT): {$(VPATH)}math.c $(RUBY_H_INCLUDES) -numeric.$(OBJEXT): {$(VPATH)}numeric.c $(RUBY_H_INCLUDES) \ +numeric.$(OBJEXT): {$(VPATH)}numeric.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \ $(ENCODING_H_INCLUDES) object.$(OBJEXT): {$(VPATH)}object.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h pack.$(OBJEXT): {$(VPATH)}pack.c $(RUBY_H_INCLUDES) diff --git a/include/ruby/util.h b/include/ruby/util.h index febd87d3e5..1c52c576da 100644 --- a/include/ruby/util.h +++ b/include/ruby/util.h @@ -40,9 +40,9 @@ extern "C" { #endif #endif -#define scan_oct ruby_scan_oct +#define scan_oct(s,l,e) (int)ruby_scan_oct(s,l,e) unsigned long ruby_scan_oct(const char *, size_t, size_t *); -#define scan_hex ruby_scan_hex +#define scan_hex(s,l,e) (int)ruby_scan_hex(s,l,e) unsigned long ruby_scan_hex(const char *, size_t, size_t *); #if defined(__CYGWIN32__) || defined(_WIN32) @@ -70,6 +70,20 @@ double ruby_strtod(const char *, char **); #undef strtod #define strtod(s,e) ruby_strtod(s,e) +#if defined _MSC_VER && _MSC_VER >= 1300 +#pragma warning(push) +#pragma warning(disable:4723) +#endif +static inline double +ruby_div0(double x) +{ + double t = 0.0; + return x / t; +} +#if defined _MSC_VER && _MSC_VER >= 1300 +#pragma warning(pop) +#endif + void ruby_each_words(const char *, void (*)(const char*, int, void*), void *); #if defined(__cplusplus) @@ -30,7 +30,7 @@ #if SIZEOF_SHORT == SIZEOF_BDIGITS #define SHORTLEN(x) (x) #else -static int +static long shortlen(long len, BDIGIT *ds) { BDIGIT num; @@ -188,7 +188,7 @@ class2path(VALUE klass) static void w_long(long, struct dump_arg*); static void -w_nbyte(const char *s, int n, struct dump_arg *arg) +w_nbyte(const char *s, long n, struct dump_arg *arg) { VALUE buf = arg->str; rb_str_buf_cat(buf, s, n); @@ -207,7 +207,7 @@ w_byte(char c, struct dump_arg *arg) } static void -w_bytes(const char *s, int n, struct dump_arg *arg) +w_bytes(const char *s, long n, struct dump_arg *arg) { w_long(n, arg); w_nbyte(s, n, arg); @@ -245,7 +245,7 @@ w_long(long x, struct dump_arg *arg) w_byte((char)((x - 5)&0xff), arg); return; } - for (i=1;i<sizeof(long)+1;i++) { + for (i=1;i<(int)sizeof(long)+1;i++) { buf[i] = (char)(x & 0xff); x = RSHIFT(x,8); if (x == 0) { @@ -306,8 +306,9 @@ save_mantissa(double d, char *buf) } static double -load_mantissa(double d, const char *buf, int len) +load_mantissa(double d, const char *buf, long len) { + if (!len) return d; if (--len > 0 && !*buf++) { /* binary mantissa mark */ int e, s = d < 0, dig = 0; unsigned long m; @@ -363,7 +364,7 @@ w_float(double d, struct dump_arg *arg) else strcpy(buf, "0"); } else { - int len; + size_t len; /* xxx: should not use system's sprintf(3) */ snprintf(buf, sizeof(buf), "%.*g", FLOAT_DIG, d); @@ -988,7 +989,7 @@ r_long(struct load_arg *arg) if (4 < c && c < 128) { return c - 5; } - if (c > sizeof(long)) long_toobig(c); + if (c > (int)sizeof(long)) long_toobig(c); x = 0; for (i=0;i<c;i++) { x |= (long)r_byte(arg) << (8*i); @@ -999,7 +1000,7 @@ r_long(struct load_arg *arg) return c + 5; } c = -c; - if (c > sizeof(long)) long_toobig(c); + if (c > (int)sizeof(long)) long_toobig(c); x = -1; for (i=0;i<c;i++) { x &= ~((long)0xff << (8*i)); @@ -1201,19 +1202,7 @@ obj_alloc_by_path(const char *path, struct load_arg *arg) return rb_obj_alloc(klass); } -#if defined _MSC_VER && _MSC_VER >= 1300 -#pragma warning(push) -#pragma warning(disable:4723) -#endif -static double -div0(double x) -{ - double t = 0.0; - return x / t; -} -#if defined _MSC_VER && _MSC_VER >= 1300 -#pragma warning(pop) -#endif +#define div0(x) ruby_div0(x) static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod) @@ -11,6 +11,7 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" +#include "ruby/util.h" #include <ctype.h> #include <math.h> #include <stdio.h> @@ -2449,19 +2450,7 @@ int_pow(long x, unsigned long y) return LONG2NUM(z); } -#if defined _MSC_VER && _MSC_VER >= 1300 -#pragma warning(push) -#pragma warning(disable:4723) -#endif -static inline double -infinite_value(void) -{ - static const double zero = 0.0; - return 1.0 / zero; -} -#if defined _MSC_VER && _MSC_VER >= 1300 -#pragma warning(pop) -#endif +#define infinite_value() ruby_div0(1.0) /* * call-seq: @@ -445,7 +445,7 @@ ruby_qsort(void* base, const size_t nel, const size_t size, register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */ char *L = base; /* left end of curren region */ char *R = (char*)base + size*(nel-1); /* right end of current region */ - int chklim = 63; /* threshold of ordering element check */ + size_t chklim = 63; /* threshold of ordering element check */ stack_node stack[32], *top = stack; /* 32 is enough for 32bit CPU */ int mmkind; size_t high, low, n; |