1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 19:37:34 +00:00

Calculator: Change internal representation to support perfect division

The purpose of this patch is to support addition, subtraction,
multiplication and division without using conversion to double. To this
end, we use the BigFraction class of LibCrypto. With this solution, we
can store values without any losses and forward rounding as the last
step before displaying.
This commit is contained in:
Lucas CHOLLET 2022-01-12 11:05:03 +01:00 committed by Sam Atkins
parent 4ab8ad2ed2
commit 53eb35caba
10 changed files with 110 additions and 361 deletions

View file

@ -7,8 +7,9 @@
#pragma once
#include "KeypadValue.h"
#include <AK/String.h>
#include <LibCrypto/BigFraction/BigFraction.h>
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
// This type implements number typing and
// displaying mechanics. It does not perform
@ -24,23 +25,27 @@ public:
void type_decimal_point();
void type_backspace();
KeypadValue value() const;
void set_value(KeypadValue);
Crypto::BigFraction value() const;
void set_value(Crypto::BigFraction);
void set_to_0();
String to_string() const;
private:
// Internal representation of the current decimal value.
bool m_negative { false };
Checked<u64> m_int_value { 0 };
Checked<u64> m_frac_value { 0 };
u8 m_frac_length { 0 };
// Those variables are only used when the user is entering a value.
// Otherwise, the BigFraction m_internal_value is used.
Crypto::UnsignedBigInteger m_int_value { 0 };
Crypto::UnsignedBigInteger m_frac_value { 0 };
Crypto::UnsignedBigInteger m_frac_length { 0 };
// E.g. for -35.004200,
// m_negative = true
// m_int_value = 35
// m_frac_value = 4200
// m_frac_length = 6
mutable Crypto::BigFraction m_internal_value {};
enum class State {
External,
TypingInteger,