ladybird/Libraries/LibCrypto/BigInt/SignedBigInteger.h
Andreas Kling b6bef6b688 Libraries: Use UTF-16 for JS-visible runtime strings
Produce JS-visible string results as UTF-16 at their source, including
numeric formatting, BigInt and BigFraction formatting, URI encoding,
console formatting, parser errors, regular expression errors, Intl and
Temporal records, LibUnicode locale boundaries, and LibWeb bindings.

Handle fractional radix formatting through the UTF-16 builder view.
2026-06-22 19:51:25 +02:00

124 lines
4.8 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2022, David Tuin <davidot@serenityos.org>
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Utf16String.h>
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
namespace Crypto {
struct SignedDivisionResult;
class SignedBigInteger {
public:
template<Signed T>
SignedBigInteger(T value)
: SignedBigInteger(static_cast<i64>(value))
{
}
SignedBigInteger(UnsignedBigInteger&& unsigned_data, bool sign);
SignedBigInteger(ReadonlyBytes);
explicit SignedBigInteger(UnsignedBigInteger const& unsigned_data);
explicit SignedBigInteger(double value);
explicit SignedBigInteger(i64 value);
SignedBigInteger(SignedBigInteger const&);
SignedBigInteger(SignedBigInteger&&);
SignedBigInteger& operator=(SignedBigInteger const&);
SignedBigInteger& operator=(SignedBigInteger&&);
SignedBigInteger();
~SignedBigInteger();
[[nodiscard]] static SignedBigInteger import_data(ReadonlyBytes data) { return SignedBigInteger(data); }
[[nodiscard]] Bytes export_data(Bytes) const;
[[nodiscard]] static ErrorOr<SignedBigInteger> from_base(u16 N, StringView str);
[[nodiscard]] static ErrorOr<SignedBigInteger> from_base(u16 N, Utf16View str);
[[nodiscard]] ErrorOr<String> to_base(u16 N) const;
[[nodiscard]] ErrorOr<Utf16String> to_base_utf16(u16 N) const;
[[nodiscard]] i64 to_i64() const;
[[nodiscard]] u64 to_u64() const;
[[nodiscard]] double to_double(UnsignedBigInteger::RoundingMode rounding_mode = UnsignedBigInteger::RoundingMode::IEEERoundAndTiesToEvenMantissa) const;
[[nodiscard]] UnsignedBigInteger unsigned_value() const;
[[nodiscard]] bool is_positive() const { return !is_negative() && !is_zero(); }
[[nodiscard]] bool is_negative() const;
[[nodiscard]] bool is_zero() const;
void negate();
void set_to_0();
void set_to(i64 other);
void set_to(SignedBigInteger const& other);
[[nodiscard]] size_t byte_length() const;
[[nodiscard]] size_t external_memory_size() const { return m_mp.alloc * sizeof(mp_digit); }
[[nodiscard]] SignedBigInteger plus(SignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger minus(SignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger bitwise_or(SignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger bitwise_and(SignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger bitwise_xor(SignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger bitwise_not() const;
[[nodiscard]] ErrorOr<SignedBigInteger> shift_left(size_t num_bits) const;
[[nodiscard]] SignedBigInteger shift_right(size_t num_bits) const;
[[nodiscard]] SignedBigInteger multiplied_by(SignedBigInteger const& other) const;
[[nodiscard]] SignedDivisionResult divided_by(SignedBigInteger const& divisor) const;
[[nodiscard]] SignedBigInteger pow(u32 exponent) const;
[[nodiscard]] ErrorOr<SignedBigInteger> mod_power_of_two(size_t power_of_two) const;
[[nodiscard]] SignedBigInteger plus(UnsignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger minus(UnsignedBigInteger const& other) const;
[[nodiscard]] SignedBigInteger multiplied_by(UnsignedBigInteger const& other) const;
[[nodiscard]] SignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const;
[[nodiscard]] SignedBigInteger negated_value() const;
[[nodiscard]] u32 hash() const;
[[nodiscard]] bool operator==(SignedBigInteger const& other) const;
[[nodiscard]] bool operator!=(SignedBigInteger const& other) const;
[[nodiscard]] bool operator<(SignedBigInteger const& other) const;
[[nodiscard]] bool operator<=(SignedBigInteger const& other) const;
[[nodiscard]] bool operator>(SignedBigInteger const& other) const;
[[nodiscard]] bool operator>=(SignedBigInteger const& other) const;
[[nodiscard]] bool operator==(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator!=(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator<(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator>(UnsignedBigInteger const& other) const;
[[nodiscard]] UnsignedBigInteger::CompareResult compare_to_double(double) const;
private:
mp_int m_mp {};
mutable Optional<u32> m_hash {};
};
struct SignedDivisionResult {
Crypto::SignedBigInteger quotient;
Crypto::SignedBigInteger remainder;
};
}
template<>
struct AK::Formatter<Crypto::SignedBigInteger> : AK::Formatter<Crypto::UnsignedBigInteger> {
ErrorOr<void> format(FormatBuilder&, Crypto::SignedBigInteger const&);
};
inline Crypto::SignedBigInteger
operator""_sbigint(char const* string, size_t length)
{
return MUST(Crypto::SignedBigInteger::from_base(10, StringView { string, length }));
}