Skip to content

Instantly share code, notes, and snippets.

@kronos
Created March 27, 2010 22:47
Show Gist options
  • Save kronos/346401 to your computer and use it in GitHub Desktop.
Save kronos/346401 to your computer and use it in GitHub Desktop.
diff --git a/vm/builtin/bignum.cpp b/vm/builtin/bignum.cpp
index 163f207..23cb377 100644
--- a/vm/builtin/bignum.cpp
+++ b/vm/builtin/bignum.cpp
@@ -96,24 +96,6 @@ namespace rubinius {
return res;
}
- static void twos_complement(mp_int *a)
- {
- long i = a->used;
- BDIGIT_DBL num;
-
- while (i--) {
- DIGIT(a,i) = (~DIGIT(a,i)) & (DIGIT_RADIX-1);
- }
-
- i = 0; num = 1;
- do {
- num += DIGIT(a,i);
- DIGIT(a,i++) = num & (DIGIT_RADIX-1);
- num = num >> DIGIT_BIT;
- } while (i < a->used);
-
- }
-
#define BITWISE_OP_AND 1
#define BITWISE_OP_OR 2
#define BITWISE_OP_XOR 3
@@ -123,19 +105,22 @@ namespace rubinius {
mp_int a, b;
mp_int *d1, *d2;
int i, sign, l1, l2;
-
+ char origin_sign_x = x->sign;
+ char origin_sign_y = y->sign;
mp_init(&a);
mp_init(&b);
if (y->sign == MP_NEG) {
mp_copy(MPST, y, &b);
- twos_complement(&b);
+ mp_neg(MPST, &b, &b);
+ mp_sub_d(MPST, &b, 1, &b);
y = &b;
}
if (x->sign == MP_NEG) {
mp_copy(MPST, x, &a);
- twos_complement(&a);
+ mp_neg(MPST, &a, &a);
+ mp_sub_d(MPST, &a, 1, &a);
x = &a;
}
@@ -176,7 +161,7 @@ namespace rubinius {
}
break;
case BITWISE_OP_XOR:
- if (x->sign != y->sign) n->sign = MP_NEG;
+ if (origin_sign_x != origin_sign_y) n->sign = MP_NEG;
for (i=0; i < l1; i++) {
DIGIT(n,i) = DIGIT(d1,i) ^ DIGIT(d2,i);
}
@@ -186,7 +171,11 @@ namespace rubinius {
break;
}
- if (n->sign == MP_NEG) twos_complement(n);
+ if (n->sign == MP_NEG) {
+ mp_neg(MPST, n, n);
+ n->sign = MP_NEG;
+ mp_sub_d(MPST, n, 1, n);
+ }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment