summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-13 09:01:11 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-13 09:01:11 +0000
commitba8fc117c58e66672b4638450e76911e42a80f7b (patch)
treee744db6e8f1628411bd65782f6fd1c516aea47b7 /bignum.c
parent1995213e4bb0b6411a4a4da60c53e37bec3ba4ec (diff)
* 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
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c106
1 files changed, 106 insertions, 0 deletions
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;