27 constexpr static int mantissa_bits = 56;
28 constexpr static int exponent_bits = 8;
29 constexpr static int exponent_max = 127;
30 constexpr static int exponent_min = -128;
32 constexpr decimal() noexcept : value(0) {}
35 constexpr decimal &operator=(
decimal const &other)
noexcept =
default;
42 decimal(std::string_view str) :
decimal(to_exponent_mantissa(str)) {}
46 constexpr decimal(
signed long x) :
decimal(0,
static_cast<signed long long>(x)) {}
47 constexpr decimal(
signed int x) :
decimal(0,
static_cast<signed long long>(x)) {}
48 constexpr decimal(
signed short x) :
decimal(0,
static_cast<signed long long>(x)) {}
49 constexpr decimal(
signed char x) :
decimal(0,
static_cast<signed long long>(x)) {}
51 constexpr decimal(
unsigned long x) :
decimal(0,
static_cast<signed long long>(x)) {}
52 constexpr decimal(
unsigned int x) :
decimal(0,
static_cast<signed long long>(x)) {}
53 constexpr decimal(
unsigned short x) :
decimal(0,
static_cast<signed long long>(x)) {}
54 constexpr decimal(
unsigned char x) :
decimal(0,
static_cast<signed long long>(x)) {}
58 value = decimal::pack(other.first, other.second);
61 decimal &operator=(std::string_view str)
noexcept
63 return *
this = to_exponent_mantissa(str);
65 constexpr decimal &operator=(
double other)
noexcept
67 return *
this = to_exponent_mantissa(other);
69 constexpr decimal &operator=(
float other)
noexcept
71 return *
this = to_exponent_mantissa(other);
73 constexpr decimal &operator=(
signed long long other)
noexcept
75 value = decimal::pack(0, other);
78 constexpr decimal &operator=(
signed long other)
noexcept
80 return *
this =
static_cast<signed long long>(other);
82 constexpr decimal &operator=(
signed int other)
noexcept
84 return *
this =
static_cast<signed long long>(other);
86 constexpr decimal &operator=(
signed short other)
noexcept
88 return *
this =
static_cast<signed long long>(other);
90 constexpr decimal &operator=(
signed char other)
noexcept
92 return *
this =
static_cast<signed long long>(other);
94 constexpr decimal &operator=(
unsigned long long other)
noexcept
96 return *
this =
static_cast<signed long long>(other);
98 constexpr decimal &operator=(
unsigned long other)
noexcept
100 return *
this =
static_cast<signed long long>(other);
102 constexpr decimal &operator=(
unsigned int other)
noexcept
104 return *
this =
static_cast<signed long long>(other);
106 constexpr decimal &operator=(
unsigned short other)
noexcept
108 return *
this =
static_cast<signed long long>(other);
110 constexpr decimal &operator=(
unsigned char other)
noexcept
112 return *
this =
static_cast<signed long long>(other);
115 explicit operator signed long long()
128 if (!is_valid_mantissa(m)) {
135 explicit operator signed long()
137 return narrow_cast<signed long>(
static_cast<signed long long>(*
this));
139 explicit operator signed int()
141 return narrow_cast<signed int>(
static_cast<signed long long>(*
this));
143 explicit operator signed short()
145 return narrow_cast<signed short>(
static_cast<signed long long>(*
this));
147 explicit operator signed char()
149 return narrow_cast<signed char>(
static_cast<signed long long>(*
this));
151 explicit operator unsigned long long()
153 return narrow_cast<unsigned int>(
static_cast<signed long long>(*
this));
155 explicit operator unsigned long()
157 return narrow_cast<unsigned long>(
static_cast<signed long long>(*
this));
159 explicit operator unsigned int()
161 return narrow_cast<unsigned int>(
static_cast<signed long long>(*
this));
163 explicit operator unsigned short()
165 return narrow_cast<unsigned short>(
static_cast<signed long long>(*
this));
167 explicit operator unsigned char()
169 return narrow_cast<unsigned char>(
static_cast<signed long long>(*
this));
171 explicit operator long double()
175 explicit operator double()
177 return static_cast<double>(
static_cast<long double>(*this));
179 explicit operator float()
181 return static_cast<float>(
static_cast<long double>(*this));
184 size_t hash()
const noexcept
194 [[nodiscard]]
constexpr int exponent() const noexcept
196 return static_cast<int8_t
>(value);
203 [[nodiscard]]
constexpr long long mantissa() const noexcept
205 return static_cast<int64_t
>(value) >> 8;
220 ttlet[e, m] = exponent_mantissa();
227 ttlet[e, lhs_m, rhs_m] = decimal::align(*
this, rhs);
228 value = decimal::pack(e, lhs_m + rhs_m);
232 decimal &operator-=(decimal rhs)
noexcept
234 ttlet[e, lhs_m, rhs_m] = decimal::align(*
this, rhs);
235 value = decimal::pack(e, lhs_m - rhs_m);
239 decimal &operator*=(decimal rhs)
noexcept
241 return *
this = *
this * rhs;
244 decimal &operator/=(decimal rhs)
noexcept
246 return *
this = *
this / rhs;
250 [[nodiscard]]
friend bool operator==(decimal lhs, decimal rhs)
noexcept
252 ttlet[e, lhs_m, rhs_m] = decimal::align(lhs, rhs);
253 return lhs_m == rhs_m;
256 [[nodiscard]]
friend bool operator<(decimal lhs, decimal rhs)
noexcept
258 ttlet[e, lhs_m, rhs_m] = decimal::align(lhs, rhs);
259 return lhs_m < rhs_m;
262 [[nodiscard]]
friend bool operator!=(decimal lhs, decimal rhs)
noexcept
264 return !(lhs == rhs);
266 [[nodiscard]]
friend bool operator>(decimal lhs, decimal rhs)
noexcept
270 [[nodiscard]]
friend bool operator<=(decimal lhs, decimal rhs)
noexcept
274 [[nodiscard]]
friend bool operator>=(decimal lhs, decimal rhs)
noexcept
279 [[nodiscard]]
friend constexpr decimal operator-(decimal rhs)
noexcept
281 return {rhs.exponent(), -rhs.mantissa()};
284 [[nodiscard]]
friend decimal operator+(decimal lhs, decimal rhs)
noexcept
286 ttlet[e, lhs_m, rhs_m] = decimal::align(lhs, rhs);
287 return {e, lhs_m + rhs_m};
290 [[nodiscard]]
friend decimal operator-(decimal lhs, decimal rhs)
noexcept
292 ttlet[e, lhs_m, rhs_m] = decimal::align(lhs, rhs);
293 return {e, lhs_m - rhs_m};
296 [[nodiscard]]
friend decimal operator*(decimal lhs, decimal rhs)
noexcept
298 auto lhs_e = lhs.exponent();
299 auto lhs_m = lhs.mantissa();
300 auto rhs_e = rhs.exponent();
301 auto rhs_m = rhs.mantissa();
304 if (!mul_overflow(lhs_m, rhs_m, &m)) {
305 [[likely]]
return {lhs_e + rhs_e, m};
311 while (mul_overflow(lhs_m, rhs_m, &m)) {
323 return {lhs_e + rhs_e, m};
326 [[nodiscard]]
friend decimal operator/(decimal lhs, decimal rhs)
noexcept
328 auto rhs_m = rhs.mantissa();
329 tt_axiom(rhs_m != 0);
330 auto rhs_e = rhs.exponent();
331 auto lhs_m = lhs.mantissa();
332 auto lhs_e = lhs.exponent();
334 std::tie(lhs_e, lhs_m) = decimal::denormalize(lhs_e, lhs_m);
335 return {lhs_e - rhs_e, lhs_m / rhs_m};
338 [[nodiscard]]
friend decimal operator%(decimal lhs, decimal rhs)
noexcept
340 auto rhs_m = rhs.mantissa();
341 tt_axiom(rhs_m != 0);
342 auto rhs_e = rhs.exponent();
343 auto lhs_m = lhs.mantissa();
344 auto lhs_e = lhs.exponent();
346 std::tie(lhs_e, lhs_m) = decimal::denormalize(lhs_e, lhs_m);
347 return {lhs_e - rhs_e, lhs_m % rhs_m};
350 [[nodiscard]]
friend std::string to_string(decimal x)
noexcept
352 auto [e, m] = x.exponent_mantissa();
355 auto decimal_position = -e;
356 auto leading_zeros = (decimal_position - std::ssize(s)) + 1;
357 if (leading_zeros > 0) {
358 s.insert(0, leading_zeros,
'0');
361 auto trailing_zeros = e;
362 if (trailing_zeros > 0) {
363 s.append(trailing_zeros,
'0');
366 if (decimal_position > 0) {
367 s.insert(s.size() - decimal_position, 1,
'.');
379 return lhs << to_string(rhs);
388 while (m % 10 == 0) {
404 while (is_valid_mantissa(m)) {
415 [[nodiscard]]
constexpr static bool is_valid_mantissa(
long long m)
noexcept
417 m >>= (mantissa_bits - 1);
418 return m == 0 || m == -1;
424 [[nodiscard]]
constexpr static bool is_valid_exponent(
int e)
noexcept
426 e >>= (exponent_bits - 1);
427 return e == 0 || e == -1;
432 auto lhs_e = lhs.exponent();
433 auto lhs_m = lhs.mantissa();
434 auto rhs_e = rhs.exponent();
435 auto rhs_m = rhs.mantissa();
437 if (lhs_e == rhs_e) {
439 }
else if (lhs_e > rhs_e) {
443 if (!is_valid_mantissa(lhs_m)) {
444 while (lhs_e > rhs_e) {
450 }
while (lhs_e > rhs_e);
455 if (!is_valid_mantissa(lhs_m)) {
456 while (lhs_e < rhs_e) {
462 }
while (lhs_e < rhs_e);
464 return {lhs_e, lhs_m, rhs_m};
469 [[nodiscard]]
constexpr static uint64_t pack(
int e,
long long m)
noexcept
472 while (!is_valid_mantissa(m)) {
473 [[unlikely]] m /= 10;
475 tt_assert(e <= exponent_max);
478 while (e > exponent_max) {
479 [[unlikely]]
if ((m *= 10) == 0)
487 tt_assert(is_valid_mantissa(m));
490 while (e < exponent_min) {
491 [[unlikely]]
if ((m /= 10) == 0)
499 return static_cast<uint64_t
>(m) << exponent_bits |
static_cast<uint8_t
>(e);
507 auto e2 =
static_cast<int>((x_ << 1) >> 53) - 1023 - 52;
508 auto m =
static_cast<long long>((x_ << 12) >> 12);
509 if (e2 > (-1023 - 52)) {
514 if (
static_cast<int64_t
>(x_) < 0) {
524 while (is_valid_mantissa(m)) {
533 while (!is_valid_mantissa(m)) {
549 int nr_digits_in_front_of_point = -1;
550 for (ttlet c : str) {
551 if (c >=
'0' && c <=
'9') {
554 }
else if (c ==
'.') {
555 nr_digits_in_front_of_point = nr_digits;
556 }
else if (c ==
'\'' || c ==
',') {
558 }
else if (c ==
'-') {
561 throw parse_error(
"Unexpected character in decimal number '{}'", str);
565 int exponent = (nr_digits_in_front_of_point >= 0) ? (nr_digits_in_front_of_point - nr_digits) : 0;
567 auto first = mantissa_str.
data();
568 auto last = first + mantissa_str.
size();
570 auto result = std::from_chars(first, last,
mantissa, 10);
571 if (result.ptr == first) {
572 throw parse_error(
"Could not parse mantissa '{}'", mantissa_str);
573 }
else if (result.ec == std::errc::result_out_of_range) {
574 throw parse_error(
"Mantissa '{}' out of range ", mantissa_str);