From ba8fc117c58e66672b4638450e76911e42a80f7b Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 13 Feb 2002 09:01:11 +0000 Subject: * parse.y (stmt): local variable declaration order was changed since 1.6 * parse.y (arg): ditto. * pack.c (pack_pack): add templates 'q' and 'Q'. * pack.c (pack_unpack): ditto. * bignum.c (rb_quad_pack): new utility function. * bignum.c (rb_quad_unpack): ditto. * parse.y (assignable): should emit CVASGN within the method body. * dir.c (dir_s_glob): should not warn even if no match found. * eval.c (rb_eval): clean up class variable behavior. * eval.c (assign): ditto. * eval.c (is_defined): ditto. * variable.c (rb_mod_class_variables): need not to call rb_cvar_singleton(). * variable.c (rb_cvar_singleton): removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- bignum.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'bignum.c') diff --git a/bignum.c b/bignum.c index 173c8fb968..c959950e7d 100644 --- a/bignum.c +++ b/bignum.c @@ -185,6 +185,112 @@ rb_int2inum(n) return rb_int2big(n); } +#ifdef HAVE_LONG_LONG + +void +rb_quad_pack(buf, val) + char *buf; + VALUE val; +{ + LONG_LONG q; + + val = rb_to_int(val); + if (FIXNUM_P(val)) { + q = FIX2LONG(val); + } + else { + long len = RBIGNUM(val)->len; + BDIGIT *ds; + + ds = BDIGITS(val); + q = 0; + while (len--) { + q = BIGUP(q); + q += ds[len]; + } + } + memcpy(buf, (char*)&q, sizeof(LONG_LONG)); +} + +VALUE +rb_quad_unpack(buf, sign) + const char *buf; + int sign; +{ + unsigned LONG_LONG q; + long neg = 0; + long i = 0; + BDIGIT *digits; + VALUE big; + + memcpy(&q, buf, sizeof(LONG_LONG)); + if (sign) { + if (FIXABLE((LONG_LONG)q)) return INT2FIX((LONG_LONG)q); + if ((LONG_LONG)q < 0) { + q = -(LONG_LONG)q; + neg = 1; + } + } + else { + if (POSFIXABLE(q)) return INT2FIX(q); + } + + i = 0; + big = bignew(DIGSPERLONGLONG, 1); + digits = BDIGITS(big); + while (i < DIGSPERLONGLONG) { + digits[i++] = BIGLO(q); + q = BIGDN(q); + } + + i = DIGSPERLONGLONG; + while (i-- && !digits[i]) ; + RBIGNUM(big)->len = i+1; + + if (neg) { + RBIGNUM(big)->sign = 0; + } + return bignorm(big); +} + +#else + +#define QUAD_SIZE 8 + +void +rb_quad_pack(buf, val) + char *buf; + VALUE val; +{ + long len; + + memset(buf, 0, QUAD_SIZE); + val = rb_to_int(val); + if (FIXNUM_P(val)) { + val = rb_uint2big(FIX2LONG(val)); + } + len = RBIGNUM(val)->len * sizeof(BDIGIT); + if (len > QUAD_SIZE) len = QUAD_SIZE; + memcpy(buf, (char*)BDIGITS(val), len); +} + +VALUE +rb_quad_unpack(buf, sign) + const char *buf; + int sign; +{ + VALUE big = bignew(QUAD_SIZE/sizeof(BDIGIT), 1); + + memcpy((char*)BDIGITS(big), buf, QUAD_SIZE); + if (sign && (buf[7] & 0x80)) { + RBIGNUM(big)->sign = 0; + } + + return bignorm(big); +} + +#endif + VALUE rb_cstr_to_inum(str, base, badcheck) const char *str; -- cgit v1.2.3