Iros
 
Loading...
Searching...
No Matches
fixed_ops.h
Go to the documentation of this file.
1#pragma once
2
12#include "di/function/equal.h"
14#include "di/types/prelude.h"
16
18using StorageType = unsigned long;
19
20template<usize words>
21struct FixedOps {
22 constexpr static auto word_index(usize bit) -> usize { return bit / (8 * sizeof(StorageType)); }
23
24 constexpr static auto get_bit(Span<StorageType const, words> storage, usize bit) -> bool {
26 auto bit_index = bit % (8 * sizeof(StorageType));
27 return (storage[word_index] & (StorageType(1) << bit_index)) != 0;
28 }
29
30 constexpr static void set_bit(Span<StorageType, words> storage, usize bit, bool value) {
32 auto bit_index = bit % (8 * sizeof(StorageType));
33 if (value) {
34 storage[word_index] |= (StorageType(1) << bit_index);
35 } else {
36 storage[word_index] &= ~(StorageType(1) << bit_index);
37 }
38 }
39
40 constexpr static auto twos_complement_negative(Span<StorageType const, words> storage) -> bool {
41 return get_bit(storage, words * 8 * sizeof(StorageType) - 1);
42 }
43
45 -> strong_ordering {
47 }
48
49 constexpr static void shift_left_one(Span<StorageType, words> value) {
50 bool carry = false;
51 for (auto& word : value) {
52 auto new_carry = word & (StorageType(1) << (8 * sizeof(StorageType) - 1));
53 word <<= 1;
54 if (carry) {
55 word |= 1;
56 }
57 carry = new_carry;
58 }
59 }
60
61 constexpr static void add_one(Span<StorageType, words> value) {
62 for (auto& word : value) {
63 if (++word != 0) {
64 break;
65 }
66 }
67 }
68
69 constexpr static void negate(Span<StorageType, words> value) {
70 for (auto& word : value) {
71 word = ~word;
72 }
73 add_one(value);
74 }
75
77 bool carry = false;
78 for (auto [x, y] : container::view::zip(a, b)) {
79 auto new_carry = x > (NumericLimits<StorageType>::max - y);
80 x += y;
81 if (carry) {
82 new_carry |= ++x == 0;
83 }
84 carry = new_carry;
85 }
86 }
87
89 auto b_negated = util::to_owned(b);
90 negate(b_negated.span());
91 add(a, b_negated);
92 }
93
96 // https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder
98
99 constexpr auto bits = 8 * sizeof(StorageType) * words;
100 for (auto i : container::view::range(bits) | container::view::reverse) {
102 set_bit(remainder, 0, get_bit(dividend, i));
103 if (compare(remainder, divisor) >= 0) {
104 subtract(remainder, divisor);
105 set_bit(quotient, i, true);
106 }
107 }
108 }
109};
110}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition span_forward_declaration.h:10
Definition bit_proxy_reference.h:5
constexpr auto zip
Definition zip.h:36
constexpr auto reverse
Definition reverse.h:52
constexpr auto range
Definition range.h:22
constexpr auto compare
Definition compare.h:40
constexpr auto all_of
Definition all_of.h:24
constexpr auto equal
Definition equal.h:23
Definition fixed_ops.h:17
unsigned long StorageType
Definition fixed_ops.h:18
size_t usize
Definition integers.h:33
constexpr auto to_owned
Definition to_owned.h:26
constexpr auto compare
Definition compare.h:19
constexpr auto remainder
Definition functions.h:110
Definition numeric_limits.h:7
Definition fixed_ops.h:21
static constexpr void set_bit(Span< StorageType, words > storage, usize bit, bool value)
Definition fixed_ops.h:30
static constexpr auto compare(Span< StorageType const, words > lhs, Span< StorageType const, words > rhs) -> strong_ordering
Definition fixed_ops.h:44
static constexpr auto word_index(usize bit) -> usize
Definition fixed_ops.h:22
static constexpr void shift_left_one(Span< StorageType, words > value)
Definition fixed_ops.h:49
static constexpr void negate(Span< StorageType, words > value)
Definition fixed_ops.h:69
static constexpr void subtract(Span< StorageType, words > a, Span< StorageType const, words > b)
Definition fixed_ops.h:88
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
static constexpr void add_one(Span< StorageType, words > value)
Definition fixed_ops.h:61
static constexpr void add(Span< StorageType, words > a, Span< StorageType const, words > b)
Definition fixed_ops.h:76
static constexpr auto get_bit(Span< StorageType const, words > storage, usize bit) -> bool
Definition fixed_ops.h:24