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

Unified Diff: runtime/vm/bigint_operations.cc

Issue 23645003: Esoteric bit operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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 | « runtime/vm/bigint_operations.h ('k') | runtime/vm/bootstrap_natives.h » ('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 7fba196e17bbb3573b825f9603dba63b86a15ed6..b7c7a69ff6ff2ea7e4b2e4c1b6ab191066b233eb 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -1291,6 +1291,34 @@ RawBigint* BigintOperations::BitNot(const Bigint& bigint) {
}
+int64_t BigintOperations::BitLength(const Bigint& bigint) {
+ ASSERT(IsClamped(bigint));
+ intptr_t length = bigint.Length();
+ if (length == 0) return 0;
+ intptr_t last = length - 1;
+
+ Chunk high_chunk = bigint.GetChunkAt(last);
+ ASSERT(high_chunk != 0);
+ int64_t bit_length =
+ static_cast<int64_t>(kDigitBitSize) * last + CountBits(high_chunk);
+
+ if (bigint.IsNegative()) {
+ // We are calculating the 2's complement bitlength but we have a sign and
+ // magnitude representation. The length is the same except when the
+ // magnitude is an exact power of two, 2^k. In 2's complement format,
+ // -(2^k) takes one fewer bit than (2^k).
+
+ if ((high_chunk & (high_chunk - 1)) == 0) { // Single bit set?
+ for (intptr_t i = 0; i < last; i++) {
+ if (bigint.GetChunkAt(i) != 0) return bit_length;
+ }
+ bit_length -= 1;
+ }
+ }
+ return bit_length;
+}
+
+
int BigintOperations::Compare(const Bigint& a, const Bigint& b) {
bool a_is_negative = a.IsNegative();
bool b_is_negative = b.IsNegative();
« no previous file with comments | « runtime/vm/bigint_operations.h ('k') | runtime/vm/bootstrap_natives.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698