BigFraction.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2022, Lucas Chollet <lucas.chollet@free.fr>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/ByteString.h>
  8. #include <LibCrypto/BigInt/SignedBigInteger.h>
  9. namespace Crypto {
  10. class BigFraction {
  11. // FIXME Make the whole API more error-friendly. This includes:
  12. // - Propagating errors from BigIntegers
  13. // - Returns errors from BigFraction(numerator, denominator);
  14. // - Duplicate fallible operators with a error-friendly version
  15. public:
  16. BigFraction() = default;
  17. explicit BigFraction(Crypto::SignedBigInteger);
  18. BigFraction(Crypto::SignedBigInteger numerator, Crypto::UnsignedBigInteger denominator);
  19. BigFraction(Crypto::BigFraction const&) = default;
  20. BigFraction(Crypto::BigFraction&&) = default;
  21. BigFraction& operator=(Crypto::BigFraction const&) = default;
  22. BigFraction& operator=(Crypto::BigFraction&&) = default;
  23. explicit BigFraction(double);
  24. static ErrorOr<BigFraction> from_string(StringView);
  25. BigFraction operator+(BigFraction const&) const;
  26. BigFraction operator-(BigFraction const&) const;
  27. BigFraction operator*(BigFraction const&) const;
  28. BigFraction operator/(BigFraction const&) const;
  29. BigFraction operator-() const;
  30. bool operator<(BigFraction const&) const;
  31. bool operator==(BigFraction const&) const;
  32. BigFraction invert() const;
  33. BigFraction sqrt() const;
  34. void set_to_0();
  35. // Return a BigFraction in "scientific notation", as an example with:
  36. // - m_numerator = 2
  37. // - m_denominator = 3
  38. // - rounding_threshold = 4
  39. // The returned BigFraction will have:
  40. // - m_numerator = 6667
  41. // - m_denominator = 10000
  42. BigFraction rounded(unsigned rounding_threshold) const;
  43. ByteString to_byte_string(unsigned rounding_threshold) const;
  44. double to_double() const;
  45. private:
  46. void reduce();
  47. // This class uses a pair of integers to store a value. The purpose is to
  48. // support any rational number without any numerical errors.
  49. // For example, if we were to represent the value -123.55 in this format,
  50. // the values could be -12355 for and 100 for m_denominator. However, this
  51. // pair of value is not unique and the value will be reduced to -2471/20.
  52. // This way, most operations don't have to be performed on doubles, but can
  53. // be performed without loss of precision on this class.
  54. Crypto::SignedBigInteger m_numerator { 0 };
  55. Crypto::UnsignedBigInteger m_denominator { 1 };
  56. };
  57. }