decstr/binary/buf/
arbitrary.rs1use core::{
2 fmt,
3 ops::Index,
4};
5
6use crate::{
7 binary::{
8 emax,
9 emin,
10 exponent::{
11 add_bias,
12 sub_bias,
13 BinaryExponent,
14 },
15 try_with_at_least_precision,
16 BinaryBuf,
17 BinaryExponentMath,
18 },
19 num::Integer,
20 OverflowError,
21};
22
23use num_bigint::BigInt;
24use num_traits::{
25 Signed,
26 ToPrimitive,
27};
28
29#[derive(Debug, Clone)]
33pub(crate) struct ArbitrarySizedBinaryBuf(Vec<u8>);
34
35pub(crate) struct ArbitrarySizedBinaryExponent(BigInt);
36
37pub(crate) struct ArbitrarySizedBinaryExponentBytes(Vec<u8>);
38
39impl BinaryBuf for ArbitrarySizedBinaryBuf {
40 type Exponent = ArbitrarySizedBinaryExponent;
41
42 fn try_exponent_from_ascii<I: Iterator<Item = u8>>(
43 is_negative: bool,
44 ascii: I,
45 ) -> Result<ArbitrarySizedBinaryExponent, OverflowError>
46 where
47 Self::Exponent: Sized,
48 {
49 ArbitrarySizedBinaryExponent::try_from_ascii(is_negative, ascii)
50 .ok_or_else(|| OverflowError::exponent_out_of_range(4, "the exponent would overflow"))
51 }
52
53 fn try_with_at_least_storage_width_bytes(bytes: usize) -> Result<Self, OverflowError> {
54 Ok(ArbitrarySizedBinaryBuf(vec![0; bytes]))
55 }
56
57 fn try_with_at_least_precision(
58 integer_digits: usize,
59 integer_exponent: Option<&Self::Exponent>,
60 ) -> Result<Self, OverflowError>
61 where
62 Self: Sized,
63 {
64 try_with_at_least_precision(integer_digits, integer_exponent.map(|e| e.0.clone()))
65 }
66
67 fn bytes_mut(&mut self) -> &mut [u8] {
68 &mut self.0
69 }
70
71 fn bytes(&self) -> &[u8] {
72 &self.0
73 }
74}
75
76impl Integer for ArbitrarySizedBinaryExponent {
77 type Bytes = ArbitrarySizedBinaryExponentBytes;
78
79 fn try_from_ascii<I: Iterator<Item = u8>>(is_negative: bool, ascii: I) -> Option<Self> {
80 Some(ArbitrarySizedBinaryExponent(Integer::try_from_ascii(
81 is_negative,
82 ascii,
83 )?))
84 }
85
86 fn from_le_bytes<I: Iterator<Item = u8>>(bytes: I) -> Self {
87 ArbitrarySizedBinaryExponent(Integer::from_le_bytes(bytes))
88 }
89
90 fn from_i32(exp: i32) -> Self {
91 ArbitrarySizedBinaryExponent(Integer::from_i32(exp))
92 }
93
94 fn to_i32(&self) -> Option<i32> {
95 Integer::to_i32(&self.0)
96 }
97
98 fn is_negative(&self) -> bool {
99 Integer::is_negative(&self.0)
100 }
101
102 fn to_le_bytes(&self) -> Self::Bytes {
103 ArbitrarySizedBinaryExponentBytes(Integer::to_le_bytes(&self.0))
104 }
105
106 fn to_fmt<W: fmt::Write>(&self, out: W) -> fmt::Result {
107 Integer::to_fmt(&self.0, out)
108 }
109}
110
111impl Integer for BigInt {
112 type Bytes = Vec<u8>;
113
114 fn try_from_ascii<I: Iterator<Item = u8>>(is_negative: bool, ascii: I) -> Option<Self>
115 where
116 Self: Sized,
117 {
118 let ascii = ascii.collect::<Vec<_>>();
119 let n = BigInt::parse_bytes(&ascii, 10)?;
120
121 Some(if is_negative { -n } else { n })
122 }
123
124 fn from_le_bytes<I: Iterator<Item = u8>>(bytes: I) -> Self {
125 let buf = bytes.collect::<Vec<_>>();
126
127 BigInt::from_signed_bytes_le(&buf)
128 }
129
130 fn from_i32(n: i32) -> Self {
131 BigInt::from(n)
132 }
133
134 fn to_i32(&self) -> Option<i32> {
135 ToPrimitive::to_i32(self)
136 }
137
138 fn is_negative(&self) -> bool {
139 Signed::is_negative(self)
140 }
141
142 fn to_le_bytes(&self) -> Self::Bytes {
143 self.to_signed_bytes_le()
144 }
145
146 fn to_fmt<W: fmt::Write>(&self, mut out: W) -> fmt::Result {
147 write!(out, "{}", self)
148 }
149}
150
151impl BinaryExponent for ArbitrarySizedBinaryExponent {
152 #[must_use]
153 fn raise(&self, integer_digits: usize) -> Self {
154 ArbitrarySizedBinaryExponent(&self.0 + integer_digits)
155 }
156
157 #[must_use]
158 fn lower(&self, fractional_digits: usize) -> Self {
159 ArbitrarySizedBinaryExponent(&self.0 - fractional_digits)
160 }
161
162 #[must_use]
163 fn bias<D: BinaryBuf>(&self, decimal: &D) -> Self {
164 ArbitrarySizedBinaryExponent(add_bias(decimal, self.0.clone()))
165 }
166
167 #[must_use]
168 fn unbias<D: BinaryBuf>(&self, decimal: &D) -> Self {
169 ArbitrarySizedBinaryExponent(sub_bias(decimal, self.0.clone()))
170 }
171
172 #[must_use]
173 fn emax<D: BinaryBuf>(decimal: &D) -> Self {
174 ArbitrarySizedBinaryExponent(emax(decimal.storage_width_bits()))
175 }
176
177 #[must_use]
178 fn emin<D: BinaryBuf>(decimal: &D) -> Self {
179 ArbitrarySizedBinaryExponent(emin(decimal.storage_width_bits()))
180 }
181}
182
183impl fmt::Display for ArbitrarySizedBinaryExponent {
184 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
185 fmt::Display::fmt(&self.0, f)
186 }
187}
188
189impl fmt::Debug for ArbitrarySizedBinaryExponent {
190 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191 fmt::Debug::fmt(&self.0, f)
192 }
193}
194
195impl Index<usize> for ArbitrarySizedBinaryExponentBytes {
196 type Output = u8;
197
198 fn index(&self, index: usize) -> &Self::Output {
199 if let Some(b) = self.0.get(index) {
203 b
204 } else {
205 &0
206 }
207 }
208}
209
210impl BinaryExponentMath for BigInt {
211 fn abs(self) -> Self {
212 Signed::abs(&self)
213 }
214
215 fn pow2(e: u32) -> Self {
216 BigInt::from(2).pow(e)
217 }
218
219 fn log2(self) -> usize {
220 let i_base2 = self.to_signed_bytes_le();
226
227 let mut significant_byte_index = i_base2.len() - 1;
228
229 while significant_byte_index > 0 {
233 if i_base2[significant_byte_index] != 0 {
234 break;
235 }
236
237 significant_byte_index -= 1;
238 }
239
240 let significant_bit_index = 8 - i_base2[significant_byte_index].leading_zeros() as usize;
241
242 let log2 = (significant_bit_index + (significant_byte_index * 8)).saturating_sub(1);
243
244 log2
245 }
246}