mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 09:17:45 +00:00
LibCrypto: Add BigFraction
This new abstraction allows the user to store rational numbers with infinite precision.
This commit is contained in:
parent
62b8ccaffc
commit
6a937312b3
3 changed files with 326 additions and 0 deletions
74
Userland/Libraries/LibCrypto/BigFraction/BigFraction.h
Normal file
74
Userland/Libraries/LibCrypto/BigFraction/BigFraction.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Lucas Chollet <lucas.chollet@free.fr>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
class BigFraction {
|
||||
// FIXME Make the whole API more error-friendly. This includes:
|
||||
// - Propagating errors from BigIntegers
|
||||
// - Returns errors from both BigFraction(StringView) and BigFraction(numerator, denominator);
|
||||
// - Duplicate fallible operators with a error-friendly version
|
||||
|
||||
public:
|
||||
BigFraction() = default;
|
||||
explicit BigFraction(Crypto::SignedBigInteger);
|
||||
BigFraction(Crypto::SignedBigInteger numerator, Crypto::UnsignedBigInteger denominator);
|
||||
|
||||
BigFraction(Crypto::BigFraction const&) = default;
|
||||
BigFraction(Crypto::BigFraction&&) = default;
|
||||
BigFraction& operator=(Crypto::BigFraction const&) = default;
|
||||
BigFraction& operator=(Crypto::BigFraction&&) = default;
|
||||
|
||||
explicit BigFraction(StringView);
|
||||
explicit BigFraction(double);
|
||||
|
||||
BigFraction operator+(BigFraction const&) const;
|
||||
BigFraction operator-(BigFraction const&) const;
|
||||
BigFraction operator*(BigFraction const&) const;
|
||||
BigFraction operator/(BigFraction const&) const;
|
||||
|
||||
BigFraction operator-() const;
|
||||
|
||||
bool operator<(BigFraction const&) const;
|
||||
bool operator==(BigFraction const&) const;
|
||||
|
||||
BigFraction invert() const;
|
||||
BigFraction sqrt() const;
|
||||
|
||||
void set_to_0();
|
||||
|
||||
// Return a BigFraction in "scientific notation", as an example with:
|
||||
// - m_numerator = 2
|
||||
// - m_denominator = 3
|
||||
// - rounding_threshold = 4
|
||||
// The returned BigFraction will have:
|
||||
// - m_numerator = 6667
|
||||
// - m_denominator = 10000
|
||||
BigFraction rounded(unsigned rounding_threshold) const;
|
||||
|
||||
String to_string(unsigned rounding_threshold) const;
|
||||
double to_double() const;
|
||||
|
||||
private:
|
||||
void reduce();
|
||||
|
||||
// This class uses a pair of integers to store a value. The purpose is to
|
||||
// support any rational number without any numerical errors.
|
||||
// For example, if we were to represent the value -123.55 in this format,
|
||||
// the values could be -12355 for and 100 for m_denominator. However, this
|
||||
// pair of value is not unique and the value will be reduced to -2471/20.
|
||||
// This way, most operations don't have to be performed on doubles, but can
|
||||
// be performed without loss of precision on this class.
|
||||
Crypto::SignedBigInteger m_numerator { 0 };
|
||||
Crypto::UnsignedBigInteger m_denominator { 1 };
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue