Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Unified Diff: runtime/vm/bigint_operations.cc

Issue 9625027: Fix bit-or and bit-xor for two negative bigints. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/bigint_operations_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/bigint_operations.cc
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index 5c633d01061dbf6ed2f193382ad3eb4c32c9cd20..428e4a82001fae19eae63b83e9b9287556346772 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -969,13 +969,14 @@ RawBigint* BigintOperations::BitOr(const Bigint& a, const Bigint& b) {
// magnitude and sign.
// a & b is therefore computed as ~((~(a - 1)) | (~(b - 1))) + 1 which is
// equal to ((a-1) & (b-1)) + 1.
+ ASSERT(a_length >= b_length);
+ ASSERT(min_length == b_length);
intptr_t result_length = min_length + 1;
const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
result.ToggleSign();
Chunk a_borrow = 1;
Chunk b_borrow = 1;
Chunk result_carry = 1;
- ASSERT(a_length >= b_length);
for (intptr_t i = 0; i < b_length; i++) {
Chunk a_digit = a.GetChunkAt(i) - a_borrow;
Chunk b_digit = b.GetChunkAt(i) - b_borrow;
@@ -985,7 +986,7 @@ RawBigint* BigintOperations::BitOr(const Bigint& a, const Bigint& b) {
b_borrow = b_digit >> (kChunkBitSize - 1);
result_carry = result_chunk >> kDigitBitSize;
}
- result.SetChunkAt(a_length, result_carry);
+ result.SetChunkAt(b_length, result_carry);
Clamp(result);
return result.raw();
}
@@ -1084,11 +1085,12 @@ RawBigint* BigintOperations::BitXor(const Bigint& a, const Bigint& b) {
// We need to convert a and b to two's complement, do the bit-operation there,
// and simply store the result.
// a ^ b is therefore computed as (~(a - 1)) ^ (~(b - 1)).
+ ASSERT(a_length >= b_length);
+ ASSERT(max_length == a_length);
intptr_t result_length = max_length;
const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
Chunk a_borrow = 1;
Chunk b_borrow = 1;
- ASSERT(a_length >= b_length);
for (intptr_t i = 0; i < b_length; i++) {
Chunk a_digit = a.GetChunkAt(i) - a_borrow;
Chunk b_digit = b.GetChunkAt(i) - b_borrow;
@@ -1100,7 +1102,8 @@ RawBigint* BigintOperations::BitXor(const Bigint& a, const Bigint& b) {
ASSERT(b_borrow == 0);
for (intptr_t i = b_length; i < a_length; i++) {
Chunk a_digit = a.GetChunkAt(i) - a_borrow;
- result.SetChunkAt(i, (~a_digit) & kDigitMask);
+ // (~a_digit) ^ 0xFFF..FFF == a_digit.
+ result.SetChunkAt(i, a_digit & kDigitMask);
a_borrow = a_digit >> (kChunkBitSize - 1);
}
ASSERT(a_borrow == 0);
« no previous file with comments | « no previous file | runtime/vm/bigint_operations_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698