1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use crate::{Integer, Int};
use crate::OverflowMode;
use crate::Byte;
use crate::Exponent;
/// Associated constants.
impl<const S: bool, const N: usize, const B: usize, const OM: u8> Integer<S, N, B, OM> {
/// The overflow mode used for this type, determined by the const-generic parameter `OM`:
/// - If `OM` is `0`, the overflow mode is [`OverflowMode::Wrap`].
/// - If `OM` is `1`, the overflow mode is [`OverflowMode::Panic`].
/// - If `OM` is `2`, the overflow mode is [`OverflowMode::Saturate`].
///
/// # Examples
///
/// ```
/// use bnum::prelude::*;
/// use bnum::OverflowMode;
///
/// type U264w = t!(U264w);
/// type I155p = t!(I155p);
/// type I512s = t!(I512s);
///
/// assert_eq!(U264w::OVERFLOW_MODE, OverflowMode::Wrap);
/// assert_eq!(I155p::OVERFLOW_MODE, OverflowMode::Panic);
/// assert_eq!(I512s::OVERFLOW_MODE, OverflowMode::Saturate);
/// ```
pub const OVERFLOW_MODE: OverflowMode = if OM == OverflowMode::Wrap.to_u8() {
OverflowMode::Wrap
} else if OM == OverflowMode::Panic.to_u8() {
OverflowMode::Panic
} else if OM == OverflowMode::Saturate.to_u8() {
OverflowMode::Saturate
} else {
panic!("invalid overflow mode: `OM` must be `0`, `1`, or `2`")
};
/// The bit width of the type.
///
/// # Examples
///
/// ```
/// use bnum::types::{U512, I1024};
///
/// assert_eq!(U512::BITS, 512);
/// assert_eq!(I1024::BITS, 1024);
/// ```
pub const BITS: Exponent = if B == 0 {
(N as Exponent) * Byte::BITS
} else {
B as _
};
/// The total number of bytes that this type contains.
///
/// # Examples
///
/// ```
/// use bnum::types::{U256, I512};
///
/// assert_eq!(U256::BYTES, 32); // 256 / 8 = 32
/// assert_eq!(I512::BYTES, 64); // 512 / 8 = 64
/// ```
pub const BYTES: Exponent = Self::BITS.div_ceil(8);
// / The value `0`.
// /
// / # Examples
// /
// / ```
// / use bnum::types::{U2048, I256};
// /
// / assert_eq!(U2048::ZERO.count_zeros(), 2048);
// / assert_eq!(n!().count_ones(), 0);
// / ```
pub(crate) const ZERO: Self = Self::from_bytes([0; N]);
// / The value `1`.
// /
// / # Examples
// /
// / ```
// / use bnum::types::{U1024, I1024};
// /
// / assert_eq!(U1024::ONE.trailing_ones(), 1);
// / assert_eq!(I1024::ONE.leading_zeros(), 1023);
// / ```
pub(crate) const ONE: Self = Self::from_byte(1);
pub(crate) const ALL_ONES: Self = Self::from_bytes([0xFF; N]);
/// The minimum value that this type can represent. For unsigned integers, this is `0`. For signed integers, this is `-2^(Self::BITS - 1)`.
///
/// # Examples
///
/// ```
/// use bnum::prelude::*;
/// use bnum::types::{U512, I512};
///
/// assert_eq!(U512::MIN, n!(0));
/// assert_eq!(I512::MIN.trailing_zeros(), 511); // memory representation is 100...0
/// ```
pub const MIN: Self = if S {
let mut bytes = [0; N];
bytes[N - 1] = Byte::MAX << (Self::LAST_BYTE_BITS - 1); // pad with ones at the end
Self::from_bytes(bytes)
} else {
Self::ZERO
};
/// The maximum value that this type can represent. For unsigned integers, this is `2^Self::BITS - 1`. For signed integers, this is `2^(Self::BITS - 1) - 1`.
///
/// # Examples
///
/// ```
/// use bnum::types::{U256, I256};
///
/// assert_eq!(U256::MAX.not(), U256::MIN); // memory representation of `Self::MAX` is 111...1
/// assert_eq!(I256::MAX.not(), I256::MIN); // memory representation of `Self::MAX` is 011...1
/// ```
pub const MAX: Self = if S {
Self::MIN.not()
} else {
let mut bytes = [0xFF; N];
bytes[N - 1] &= Byte::MAX >> Self::LAST_BYTE_PAD_BITS; // pad with zeros at the end
Self::from_bytes(bytes)
};
}
impl<const N: usize, const B: usize, const OM: u8> Int<N, B, OM> {
// / The value `-1`.
// /
// / # Examples
// /
// / ```
// / use bnum::types::I256;
// /
// / assert_eq!(I256::NEG_ONE.count_ones(), 256); // memory representation is 111...1
// / ```
pub(crate) const NEG_ONE: Self = Self::ALL_ONES;
}