mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 11:57:35 +00:00
LibCrypto+LibJS: Better bigint bitwise_and binop
Bitwise and is defined in terms of two's complement, so some converting needs to happen for SignedBigInteger's sign/magnitude representation to work out. UnsignedBigInteger::bitwise_not() is repurposed to convert all high-order zero bits to ones up to a limit, for the two's complement conversion to work. Fixes test262/test/language/expressions/bitwise-and/bigint.js.
This commit is contained in:
parent
945d962322
commit
1f98639396
7 changed files with 52 additions and 23 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "UnsignedBigIntegerAlgorithms.h"
|
||||
#include <AK/BuiltinWrappers.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
|
@ -130,8 +131,9 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_xor_without_allocation(
|
|||
/**
|
||||
* Complexity: O(N) where N is the number of words
|
||||
*/
|
||||
FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_without_allocation(
|
||||
FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_size_without_allocation(
|
||||
UnsignedBigInteger const& right,
|
||||
size_t size,
|
||||
UnsignedBigInteger& output)
|
||||
{
|
||||
// If the value is invalid, the output value is invalid as well.
|
||||
|
@ -139,22 +141,17 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_without_allocation(
|
|||
output.invalidate();
|
||||
return;
|
||||
}
|
||||
if (right.length() == 0) {
|
||||
if (size == 0) {
|
||||
output.set_to_0();
|
||||
return;
|
||||
}
|
||||
|
||||
output.m_words.resize_and_keep_capacity(right.length());
|
||||
|
||||
if (right.length() > 1) {
|
||||
for (size_t i = 0; i < right.length() - 1; ++i)
|
||||
output.m_words[i] = ~right.words()[i];
|
||||
}
|
||||
|
||||
auto last_word_index = right.length() - 1;
|
||||
auto last_word = right.words()[last_word_index];
|
||||
|
||||
output.m_words[last_word_index] = ((u32)0xffffffffffffffff >> count_leading_zeroes(last_word)) & ~last_word;
|
||||
output.m_words.resize_and_keep_capacity(size);
|
||||
size_t i;
|
||||
for (i = 0; i < min(size, right.length()); ++i)
|
||||
output.m_words[i] = ~right.words()[i];
|
||||
for (; i < size; ++i)
|
||||
output.m_words[i] = NumericLimits<UnsignedBigInteger::Word>::max();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue