1use crate::{
2 binary::{
3 encode_max,
4 encode_min,
5 FixedBinaryBuf,
6 },
7 text::ArrayTextBuf,
8};
9
10#[derive(Clone, Copy)]
14pub struct Bitstring64(FixedBinaryBuf<8, i32>);
15
16impl Bitstring64 {
20 pub const ZERO: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 56, 34]));
22
23 pub const ONE: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 56, 34]));
25
26 pub const NEG_ONE: Self =
28 Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 56, 162]));
29
30 pub const PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
32 187, 63, 59, 181, 174, 193, 252, 45,
33 ]));
34
35 pub const TAU: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
39 234, 230, 115, 216, 50, 43, 253, 57,
40 ]));
41
42 pub const FRAC_PI_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
44 30, 107, 111, 154, 254, 240, 254, 37,
45 ]));
46
47 pub const FRAC_PI_3: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
49 251, 234, 19, 237, 62, 71, 252, 37,
50 ]));
51
52 pub const FRAC_PI_4: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
54 72, 238, 55, 142, 119, 203, 255, 33,
55 ]));
56
57 pub const FRAC_PI_6: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
59 94, 121, 91, 191, 183, 163, 254, 33,
60 ]));
61
62 pub const FRAC_PI_8: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
64 164, 123, 189, 192, 215, 186, 253, 33,
65 ]));
66
67 pub const FRAC_1_PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
69 154, 175, 226, 112, 98, 152, 253, 33,
70 ]));
71
72 pub const FRAC_2_PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
74 139, 158, 39, 127, 198, 54, 255, 33,
75 ]));
76
77 pub const FRAC_2_SQRT_PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
79 146, 110, 113, 78, 126, 168, 252, 37,
80 ]));
81
82 pub const SQRT_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
84 91, 204, 39, 238, 68, 20, 254, 37,
85 ]));
86
87 pub const FRAC_1_SQRT_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
89 199, 170, 179, 184, 33, 135, 255, 33,
90 ]));
91
92 pub const E: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
94 69, 100, 233, 210, 66, 152, 255, 41,
95 ]));
96
97 pub const LOG2_10: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
99 226, 61, 172, 133, 107, 161, 253, 45,
100 ]));
101
102 pub const LOG2_E: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
104 237, 185, 1, 196, 214, 66, 254, 37,
105 ]));
106
107 pub const LOG10_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
109 143, 140, 253, 105, 10, 129, 253, 33,
110 ]));
111
112 pub const LOG10_E: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
114 81, 53, 182, 160, 86, 52, 254, 33,
115 ]));
116
117 pub const LN_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
119 205, 102, 171, 200, 49, 59, 255, 33,
120 ]));
121
122 pub const LN_10: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
124 69, 120, 170, 195, 178, 130, 253, 41,
125 ]));
126}
127
128impl Bitstring64 {
129 pub const RADIX: u32 = 10;
131
132 pub const DIGITS: u32 = 16;
140
141 pub const EPSILON: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 0, 34]));
149
150 pub const MIN: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
152 255, 252, 243, 207, 63, 255, 248, 247,
153 ]));
154
155 pub const MIN_POSITIVE: Self =
157 Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 0, 0]));
158
159 pub const MAX: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
161 255, 252, 243, 207, 63, 255, 248, 119,
162 ]));
163
164 pub const MIN_10_EXP: i32 = -398;
166
167 pub const MAX_10_EXP: i32 = 369;
169
170 pub const NAN: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 0, 124]));
172
173 pub const INFINITY: Self =
175 Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 0, 120]));
176
177 pub const NEG_INFINITY: Self =
179 Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 0, 248]));
180}
181
182impl Bitstring64 {
183 #[inline]
189 pub const fn from_le_bytes(bytes: [u8; 8]) -> Self {
190 Self(FixedBinaryBuf::from_le_bytes(bytes))
191 }
192
193 #[inline]
197 pub const fn from_be_bytes(bytes: [u8; 8]) -> Self {
198 Self(FixedBinaryBuf::from_le_bytes([
199 bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0],
200 ]))
201 }
202
203 #[inline]
209 pub const fn as_le_bytes(&self) -> &[u8; 8] {
210 self.0.as_le_bytes()
212 }
213
214 #[inline]
219 pub const fn to_be_bytes(&self) -> [u8; 8] {
220 let b = self.0.as_le_bytes();
221 [b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]]
222 }
223
224 pub fn zero() -> Self {
228 Self::from(0u8)
229 }
230
231 pub fn max() -> Self {
235 let mut buf = FixedBinaryBuf::ZERO;
236
237 encode_max(&mut buf, false);
238
239 Self(buf)
240 }
241
242 pub fn min() -> Self {
246 let mut buf = FixedBinaryBuf::ZERO;
247
248 encode_max(&mut buf, true);
249
250 Self(buf)
251 }
252
253 pub fn min_positive() -> Self {
257 let mut buf = FixedBinaryBuf::ZERO;
258
259 encode_min(&mut buf, false);
260
261 Self(buf)
262 }
263}
264
265classify!(Bitstring64);
266
267try_s2d!(ArrayTextBuf::<64> => Bitstring64);
268d2s!(Bitstring64);
269
270f2d!(f32 => from_f32 => Bitstring64);
271try_f2d!(f64 => from_f64 => Bitstring64);
272
273try_d2f!(Bitstring64 => to_f32 => f32);
274try_d2f!(Bitstring64 => to_f64 => f64);
275
276i2d!(i8 => from_i8 => Bitstring64);
277i2d!(i16 => from_i16 => Bitstring64);
278i2d!(i32 => from_i32 => Bitstring64);
279try_i2d!(i64 => from_i64 => Bitstring64);
280try_i2d!(i128 => from_i128 => Bitstring64);
281
282try_d2i!(Bitstring64 => to_i8 => i8);
283try_d2i!(Bitstring64 => to_i16 => i16);
284try_d2i!(Bitstring64 => to_i32 => i32);
285try_d2i!(Bitstring64 => to_i64 => i64);
286try_d2i!(Bitstring64 => to_i128 => i128);
287
288i2d!(u8 => from_u8 => Bitstring64);
289i2d!(u16 => from_u16 => Bitstring64);
290i2d!(u32 => from_u32 => Bitstring64);
291try_i2d!(u64 => from_u64 => Bitstring64);
292try_i2d!(u128 => from_u128 => Bitstring64);
293
294try_d2i!(Bitstring64 => to_u8 => u8);
295try_d2i!(Bitstring64 => to_u16 => u16);
296try_d2i!(Bitstring64 => to_u32 => u32);
297try_d2i!(Bitstring64 => to_u64 => u64);
298try_d2i!(Bitstring64 => to_u128 => u128);
299
300#[cfg(test)]
301mod tests {
302 use super::*;
303
304 #[test]
305 fn consts_64() {
306 use core::str::FromStr;
307
308 fn is_eq(a: Bitstring64, b: Bitstring64) {
310 assert_eq!(a.as_le_bytes(), b.as_le_bytes());
311 }
312 fn is_eq_f(a: Bitstring64, s: &str) {
314 assert_eq!(
315 a.to_string(),
316 s.chars()
317 .take((Bitstring64::DIGITS + 1) as usize)
318 .collect::<String>()
319 );
320 }
321
322 is_eq(Bitstring64::ZERO, Bitstring64::from_str("0").unwrap());
323 is_eq(Bitstring64::ONE, Bitstring64::from_str("1").unwrap());
324 is_eq(Bitstring64::NEG_ONE, Bitstring64::from_str("-1").unwrap());
325
326 const PI: &str = "3.14159265358979323846264338327950288";
328 const TAU: &str = "6.28318530717958647692528676655900577";
329 const FRAC_PI_2: &str = "1.57079632679489661923132169163975144";
330 const FRAC_PI_3: &str = "1.04719755119659774615421446109316763";
331 const FRAC_PI_4: &str = "0.785398163397448309615660845819875721";
332 const FRAC_PI_6: &str = "0.52359877559829887307710723054658381";
333 const FRAC_PI_8: &str = "0.39269908169872415480783042290993786";
334 const FRAC_1_PI: &str = "0.318309886183790671537767526745028724";
335 const FRAC_2_PI: &str = "0.636619772367581343075535053490057448";
336 const FRAC_2_SQRT_PI: &str = "1.12837916709551257389615890312154517";
337 const SQRT_2: &str = "1.41421356237309504880168872420969808";
338 const FRAC_1_SQRT_2: &str = "0.707106781186547524400844362104849039";
339 const E: &str = "2.71828182845904523536028747135266250";
340 const LOG2_10: &str = "3.32192809488736234787031942948939018";
341 const LOG2_E: &str = "1.44269504088896340735992468100189214";
342 const LOG10_2: &str = "0.301029995663981195213738894724493027";
343 const LOG10_E: &str = "0.434294481903251827651128918916605082";
344 const LN_2: &str = "0.693147180559945309417232121458176568";
345 const LN_10: &str = "2.30258509299404568401799145468436421";
346
347 is_eq_f(Bitstring64::PI, PI);
348 is_eq_f(Bitstring64::TAU, TAU);
349 is_eq_f(Bitstring64::FRAC_PI_2, FRAC_PI_2);
350 is_eq_f(Bitstring64::FRAC_PI_3, FRAC_PI_3);
351 is_eq_f(Bitstring64::FRAC_PI_4, FRAC_PI_4);
352 is_eq_f(Bitstring64::FRAC_PI_6, FRAC_PI_6);
353 is_eq_f(Bitstring64::FRAC_PI_8, FRAC_PI_8);
354 is_eq_f(Bitstring64::FRAC_1_PI, FRAC_1_PI);
355 is_eq_f(Bitstring64::FRAC_2_PI, FRAC_2_PI);
356 is_eq_f(Bitstring64::FRAC_2_SQRT_PI, FRAC_2_SQRT_PI);
357 is_eq_f(Bitstring64::SQRT_2, SQRT_2);
358 is_eq_f(Bitstring64::FRAC_1_SQRT_2, FRAC_1_SQRT_2);
359 is_eq_f(Bitstring64::E, E);
360 is_eq_f(Bitstring64::LOG2_10, LOG2_10);
361 is_eq_f(Bitstring64::LOG2_E, LOG2_E);
362 is_eq_f(Bitstring64::LOG10_2, LOG10_2);
363 is_eq_f(Bitstring64::LOG10_E, LOG10_E);
364 is_eq_f(Bitstring64::LN_2, LN_2);
365 is_eq_f(Bitstring64::LN_10, LN_10);
366
367 is_eq(
369 Bitstring64::EPSILON,
370 Bitstring64::from_str("0.00000000000001").unwrap(),
371 );
372 is_eq(Bitstring64::MIN, Bitstring64::min());
373 is_eq(Bitstring64::MIN_POSITIVE, Bitstring64::min_positive());
374 is_eq(Bitstring64::MAX, Bitstring64::max());
375 is_eq(Bitstring64::NAN, Bitstring64::from_str("nan").unwrap());
376 is_eq(Bitstring64::INFINITY, Bitstring64::from_str("inf").unwrap());
377 is_eq(
378 Bitstring64::NEG_INFINITY,
379 Bitstring64::from_str("-inf").unwrap(),
380 );
381
382 assert_eq!(
383 Bitstring64::MIN_10_EXP,
384 crate::binary::emin::<i32>(64) - (Bitstring64::DIGITS as i32) + 1
385 );
386 assert_eq!(
387 Bitstring64::MAX_10_EXP,
388 crate::binary::emax::<i32>(64) - (Bitstring64::DIGITS as i32) + 1
389 );
390 }
391}