Calculator: Construct KeypadValue precisely from the Clipboard contents

Previously, we would use lossy strtod() conversion. This was bad,
especially since we switched from internally storing Calculator
state in a double to storing it in the KeypadValue class
some time ago. This commit adds a constructor for the KeypadValue
class that is not lossy by using strtoll(). It handles numbers
with and without decimal points as well as negative numbers
correctly.
This commit is contained in:
creator1creeper1 2021-12-19 19:07:53 +01:00 committed by Brian Gianforcaro
parent 7ea3d40e19
commit cacac7927b
Notes: sideshowbarker 2024-07-17 22:26:32 +09:00
3 changed files with 22 additions and 2 deletions

View file

@ -19,6 +19,25 @@ KeypadValue::KeypadValue(i64 value)
{
}
KeypadValue::KeypadValue(StringView sv)
{
String str = sv.to_string(); //TODO: Once we have a StringView equivalent for this C API, we won't need to create a copy for this anymore.
size_t first_index = 0;
char* dot_ptr;
i64 int_part = strtoll(&str[first_index], &dot_ptr, 10);
size_t dot_index = dot_ptr - str.characters();
if ((dot_index < str.length()) && (str[dot_index] == '.')) {
size_t second_index = dot_index + 1;
char* end_ptr;
i64 frac_part = strtoll(&str[second_index], &end_ptr, 10);
size_t end_index = end_ptr - str.characters();
u8 frac_length = end_index - second_index;
*this = KeypadValue { int_part } + KeypadValue { frac_part, frac_length };
} else {
*this = KeypadValue { int_part };
}
};
KeypadValue KeypadValue::operator+(KeypadValue const& rhs)
{
return operator_helper<KeypadValue>(*this, rhs, [](KeypadValue const&, KeypadValue const& more_decimal_places, i64 less_decimal_places_equalized, i64 more_decimal_places_equalized, bool) -> KeypadValue {

View file

@ -17,6 +17,8 @@ public:
KeypadValue(i64, u8);
KeypadValue(i64);
explicit KeypadValue(StringView);
KeypadValue operator+(KeypadValue const&);
KeypadValue operator-(KeypadValue const&);
KeypadValue operator*(KeypadValue const&);

View file

@ -51,8 +51,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto clipboard = GUI::Clipboard::the().fetch_data_and_type();
if (clipboard.mime_type == "text/plain") {
if (!clipboard.data.is_empty()) {
auto data = atof(StringView(clipboard.data).to_string().characters());
widget.set_entry(KeypadValue { data });
widget.set_entry(KeypadValue(StringView(clipboard.data)));
}
}
}));