Iros
 
Loading...
Searching...
No Matches
fixed_signed.h
Go to the documentation of this file.
1#pragma once
2
4#include "di/types/prelude.h"
7
8namespace di::math {
15template<usize bits>
16requires(bits % sizeof(bigint::StorageType) == 0)
18private:
19 constexpr static usize word_count = bits / sizeof(bigint::StorageType) / 8;
20
22
23public:
24 FixedSigned() = default;
25
26 constexpr FixedSigned(bigint::StorageType value) { m_storage[0] = value; }
27
28 constexpr auto operator/(FixedSigned const& divisor) const -> FixedSigned {
29 auto division_result = FixedSigned();
30 auto modulo_result = FixedSigned();
31 auto dividend_negative = Ops::twos_complement_negative(this->span());
32 auto divisor_negative = Ops::twos_complement_negative(divisor.span());
33 switch (dividend_negative + 2 * divisor_negative) {
34 // + / + -> -
35 case 0: {
36 Ops::div_mod(this->span(), divisor.span(), division_result.span(), modulo_result.span());
37 break;
38 }
39 // - / + -> -
40 case 1: {
41 auto dividend = *this;
42 Ops::negate(dividend.span());
43 Ops::div_mod(dividend.span(), divisor.span(), division_result.span(), modulo_result.span());
44 Ops::negate(division_result.span());
45 break;
46 }
47 // + / - -> -
48 case 2: {
49 auto divisor_copy = divisor;
50 Ops::negate(divisor_copy.span());
51 Ops::div_mod(this->span(), divisor_copy.span(), division_result.span(), modulo_result.span());
52 Ops::negate(division_result.span());
53 break;
54 }
55 // - / - -> +
56 case 3: {
57 auto dividend = *this;
58 auto divisor_copy = divisor;
59 Ops::negate(dividend.span());
60 Ops::negate(divisor_copy.span());
61 Ops::div_mod(dividend.span(), divisor_copy.span(), division_result.span(), modulo_result.span());
62 break;
63 }
64 }
65 return division_result;
66 }
67
68 constexpr auto operator%(FixedSigned const& divisor) const -> FixedSigned {
69 auto division_result = FixedSigned();
70 auto modulo_result = FixedSigned();
71 auto dividend_negative = Ops::twos_complement_negative(this->span());
72 auto divisor_negative = Ops::twos_complement_negative(divisor.span());
73 switch (dividend_negative + 2 * divisor_negative) {
74 // + % + -> -
75 case 0: {
76 Ops::div_mod(this->span(), divisor.span(), division_result.span(), modulo_result.span());
77 break;
78 }
79 // - % + -> -
80 case 1: {
81 auto dividend = *this;
82 Ops::negate(dividend.span());
83 Ops::div_mod(dividend.span(), divisor.span(), division_result.span(), modulo_result.span());
84 Ops::negate(modulo_result.span());
85 break;
86 }
87 // + % - -> +
88 case 2: {
89 auto divisor_copy = divisor;
90 Ops::negate(divisor_copy.span());
91 Ops::div_mod(this->span(), divisor_copy.span(), division_result.span(), modulo_result.span());
92 break;
93 }
94 // - % - -> -
95 case 3: {
96 auto dividend = *this;
97 auto divisor_copy = divisor;
98 Ops::negate(dividend.span());
99 Ops::negate(divisor_copy.span());
100 Ops::div_mod(dividend.span(), divisor_copy.span(), division_result.span(), modulo_result.span());
101 Ops::negate(modulo_result.span());
102 break;
103 }
104 }
105 return modulo_result;
106 }
107
108 constexpr auto operator-() const -> FixedSigned {
109 auto result = *this;
110 Ops::negate(result.span());
111 return result;
112 }
113
114private:
115 constexpr friend auto operator==(FixedSigned const& a, FixedSigned const& b) -> bool {
116 return Ops::compare(a.span(), b.span()) == 0;
117 }
118
119 constexpr friend auto operator<=>(FixedSigned const& a, FixedSigned const& b) {
120 if (auto result = Ops::twos_complement_negative(a.span()) <=> Ops::twos_complement_negative(b.span());
121 result != 0) {
122 return result;
123 }
124 return Ops::compare(a.span(), b.span());
125 }
126
127 constexpr auto span() { return m_storage.span(); }
128 constexpr auto span() const { return m_storage.span(); }
129
131};
132
135}
136
137namespace di {
140using math::i256;
141}
A fixed-width signed integer.
Definition fixed_signed.h:17
constexpr friend auto operator==(FixedSigned const &a, FixedSigned const &b) -> bool
Definition fixed_signed.h:115
constexpr friend auto operator<=>(FixedSigned const &a, FixedSigned const &b)
Definition fixed_signed.h:119
constexpr auto operator%(FixedSigned const &divisor) const -> FixedSigned
Definition fixed_signed.h:68
constexpr auto operator-() const -> FixedSigned
Definition fixed_signed.h:108
constexpr auto operator/(FixedSigned const &divisor) const -> FixedSigned
Definition fixed_signed.h:28
constexpr FixedSigned(bigint::StorageType value)
Definition fixed_signed.h:26
unsigned long StorageType
Definition fixed_ops.h:18
Definition abs.h:10
FixedSigned< 256 > i256
Definition fixed_signed.h:134
FixedSigned< 128 > i128_fallback
Definition fixed_signed.h:133
size_t usize
Definition integers.h:33
Definition zstring_parser.h:9
Definition fixed_ops.h:21
static constexpr auto compare(Span< StorageType const, words > lhs, Span< StorageType const, words > rhs) -> strong_ordering
Definition fixed_ops.h:44
static constexpr void negate(Span< StorageType, words > value)
Definition fixed_ops.h:69
static constexpr void div_mod(Span< StorageType const, words > dividend, Span< StorageType const, words > divisor, Span< StorageType, words > quotient, Span< StorageType, words > remainder)
Definition fixed_ops.h:94
static constexpr auto twos_complement_negative(Span< StorageType const, words > storage) -> bool
Definition fixed_ops.h:40
Definition span_fixed_size.h:37