byte_unit/bit/
mod.rs

1mod adjusted;
2mod built_in_traits;
3mod constants;
4mod decimal;
5mod parse;
6#[cfg(feature = "rocket")]
7mod rocket_traits;
8#[cfg(feature = "serde")]
9mod serde_traits;
10
11use core::fmt::{self, Alignment, Display, Formatter, Write};
12
13pub use adjusted::*;
14use rust_decimal::prelude::*;
15
16use crate::{
17    common::{ceil_f32, ceil_f64},
18    Unit,
19};
20
21#[cfg(feature = "u128")]
22const RONNABIT: u128 = 1_000_000_000_000_000_000_000_000_000; // RB
23
24#[cfg(feature = "u128")]
25#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
26/// Representing the size in bits.
27pub struct Bit(u128);
28
29#[cfg(not(feature = "u128"))]
30#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
31/// Representing the size in bits.
32pub struct Bit(u64);
33
34impl Display for Bit {
35    /// Formats the value using the given formatter.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use byte_unit::{Bit, Unit};
41    ///
42    /// let bit = Bit::from_u64_with_unit(1555, Unit::Kbit).unwrap();
43    ///
44    /// assert_eq!("1555000", bit.to_string());
45    /// ```
46    ///
47    /// ```
48    /// use byte_unit::{Bit, UnitType};
49    ///
50    /// let bit_based_2 = Bit::from_u64(10240);
51    /// let bit_based_10 = Bit::from_u64(10000);
52    ///
53    /// assert_eq!("10240", format!("{bit_based_2}"));
54    /// assert_eq!("10000", format!("{bit_based_10}"));
55    ///
56    /// // with an exact unit
57    /// assert_eq!("10 Kib", format!("{bit_based_2:#}"));
58    /// assert_eq!("10 Kb", format!("{bit_based_10:#}"));
59    ///
60    /// // with an exact unit, no spaces between the value and the unit
61    /// assert_eq!("10Kib", format!("{bit_based_2:-#}"));
62    /// assert_eq!("10Kb", format!("{bit_based_10:-#}"));
63    ///
64    /// // with a width, left alignment
65    /// assert_eq!("10     Kib", format!("{bit_based_2:#10}"));
66    /// assert_eq!("10      Kb", format!("{bit_based_10:#10}"));
67    ///
68    /// // with a width, right alignment
69    /// assert_eq!("    10 Kib", format!("{bit_based_2:>#10}"));
70    /// assert_eq!("     10 Kb", format!("{bit_based_10:>#10}"));
71    ///
72    /// // with a width, right alignment, more spaces between the value and the unit
73    /// assert_eq!("    10 Kib", format!("{bit_based_2:>+#10}"));
74    /// assert_eq!("    10  Kb", format!("{bit_based_10:>+#10}"));
75    /// ```
76    ///
77    /// ```
78    /// use byte_unit::{Bit, UnitType};
79    ///
80    /// let bit = Bit::from_u64(3211776);
81    ///
82    /// assert_eq!("3211776", format!("{bit}"));
83    ///
84    /// // with a unit, still precisely
85    /// assert_eq!("3136.5 Kib", format!("{bit:#}"));
86    ///
87    /// // with a unit and a larger precision (default is 3), still precisely
88    /// assert_eq!("3.211776 Mb", format!("{bit:#.6}"));
89    ///
90    /// // with a unit and a smaller precision (default is 3), still precisely
91    /// assert_eq!("3211776 b", format!("{bit:#.0}"));
92    /// ```
93    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
94        if f.alternate() {
95            let precision = f.precision().unwrap_or(3);
96
97            let (mut value, unit) = self.get_recoverable_unit(false, precision);
98
99            value = value.normalize();
100
101            let space_length = if f.sign_plus() {
102                4 - unit.as_str().len()
103            } else if f.sign_minus() {
104                0
105            } else {
106                1
107            };
108
109            if let Some(mut width) = f.width() {
110                let l = unit.as_str().len() + space_length;
111
112                if width > l + 1 {
113                    width -= l;
114
115                    let alignment = f.align().unwrap_or(Alignment::Left);
116
117                    match alignment {
118                        Alignment::Left | Alignment::Center => {
119                            f.write_fmt(format_args!("{value:<width$}"))?
120                        },
121                        Alignment::Right => f.write_fmt(format_args!("{value:>width$}"))?,
122                    }
123                } else {
124                    f.write_fmt(format_args!("{value}"))?;
125                }
126            } else {
127                f.write_fmt(format_args!("{value}"))?;
128            }
129
130            for _ in 0..space_length {
131                f.write_char(' ')?;
132            }
133
134            f.write_fmt(format_args!("{unit}"))
135        } else {
136            Display::fmt(&self.0, f)
137        }
138    }
139}
140
141/// Associated functions for building `Bit` instances.
142impl Bit {
143    /// Create a new `Bit` instance from a size in bits.
144    ///
145    /// # Examples
146    ///
147    /// ```
148    /// # use byte_unit::Bit;
149    /// let bit = Bit::from_u128(15000000).unwrap(); // 15 Mb
150    /// ```
151    ///
152    /// # Points to Note
153    ///
154    /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise), this function will return `None`.
155    #[inline]
156    pub const fn from_u128(size: u128) -> Option<Self> {
157        #[cfg(feature = "u128")]
158        {
159            if size < RONNABIT {
160                Some(Bit(size))
161            } else {
162                None
163            }
164        }
165
166        #[cfg(not(feature = "u128"))]
167        {
168            if size <= u64::MAX as u128 {
169                Some(Bit(size as u64))
170            } else {
171                None
172            }
173        }
174    }
175
176    /// Create a new `Bit` instance from a size in bits.
177    ///
178    /// # Examples
179    ///
180    /// ```
181    /// # use byte_unit::Bit;
182    /// let bit = unsafe { Bit::from_u128_unsafe(15000000) }; // 15 Mb
183    /// ```
184    ///
185    /// # Safety
186    /// You must ensure the input **size** is not too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) on your own.
187    #[inline]
188    pub const unsafe fn from_u128_unsafe(size: u128) -> Self {
189        #[cfg(feature = "u128")]
190        {
191            Bit(size)
192        }
193
194        #[cfg(not(feature = "u128"))]
195        {
196            Bit(size as u64)
197        }
198    }
199
200    /// Create a new `Bit` instance from a size in bits.
201    ///
202    /// # Examples
203    ///
204    /// ```
205    /// # use byte_unit::Bit;
206    /// let bit = Bit::from_u64(15000000); // 15 Mb
207    /// ```
208    #[inline]
209    pub const fn from_u64(size: u64) -> Self {
210        #[cfg(feature = "u128")]
211        {
212            Bit(size as u128)
213        }
214
215        #[cfg(not(feature = "u128"))]
216        {
217            Bit(size)
218        }
219    }
220
221    /// Create a new `Bit` instance from a size in bits.
222    ///
223    /// # Examples
224    ///
225    /// ```
226    /// # use byte_unit::Bit;
227    /// let bit = Bit::from_f64(15000000.0).unwrap(); // 15 Mb
228    /// ```
229    ///
230    /// # Points to Note
231    ///
232    /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) or not greater than or equal to **0**, this function will return `None`.
233    /// * The fractional part will be rounded up.
234    #[inline]
235    pub fn from_f64(size: f64) -> Option<Self> {
236        if size >= 0.0 {
237            #[cfg(feature = "u128")]
238            {
239                let size = ceil_f64(size) as u128;
240
241                if size < RONNABIT {
242                    Some(Bit(size))
243                } else {
244                    None
245                }
246            }
247
248            #[cfg(not(feature = "u128"))]
249            {
250                let size = ceil_f64(size) as u64;
251
252                if size < u64::MAX {
253                    Some(Bit(size))
254                } else {
255                    None
256                }
257            }
258        } else {
259            None
260        }
261    }
262
263    /// Create a new `Bit` instance from a size in bits.
264    ///
265    /// # Examples
266    ///
267    /// ```
268    /// # use byte_unit::Bit;
269    /// let bit = Bit::from_f32(15000000.0).unwrap(); // 15 Mb
270    /// ```
271    ///
272    /// # Points to Note
273    ///
274    /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) or not greater than or equal to **0**, this function will return `None`.
275    /// * The fractional part will be rounded up.
276    #[inline]
277    pub fn from_f32(size: f32) -> Option<Self> {
278        if size >= 0.0 {
279            #[cfg(feature = "u128")]
280            {
281                let size = ceil_f32(size) as u128;
282
283                if size < RONNABIT {
284                    Some(Bit(size))
285                } else {
286                    None
287                }
288            }
289
290            #[cfg(not(feature = "u128"))]
291            {
292                let size = ceil_f32(size) as u64;
293
294                if size < u64::MAX {
295                    Some(Bit(size))
296                } else {
297                    None
298                }
299            }
300        } else {
301            None
302        }
303    }
304
305    /// Create a new `Bit` instance from a size in bits.
306    ///
307    /// # Examples
308    ///
309    /// ```
310    /// # use byte_unit::Bit;
311    /// let bit = Bit::from_i128(15000000).unwrap(); // 15 Mb
312    /// ```
313    ///
314    /// # Points to Note
315    ///
316    /// * If the input **size** is too large (the maximum is **10<sup>27</sup> - 1** if the `u128` feature is enabled, or **2<sup>64</sup> - 1** otherwise) or negative, this function will return `None`.
317    #[inline]
318    pub const fn from_i128(size: i128) -> Option<Self> {
319        if size >= 0 {
320            Self::from_u128(size as u128)
321        } else {
322            None
323        }
324    }
325
326    /// Create a new `Bit` instance from a size in bits.
327    ///
328    /// # Examples
329    ///
330    /// ```
331    /// # use byte_unit::Bit;
332    /// let bit = Bit::from_i64(15000000).unwrap(); // 15 Mb
333    /// ```
334    ///
335    /// # Points to Note
336    ///
337    /// * If the input **size** is negative, this function will return `None`.
338    #[inline]
339    pub const fn from_i64(size: i64) -> Option<Self> {
340        if size >= 0 {
341            Some(Self::from_u64(size as u64))
342        } else {
343            None
344        }
345    }
346}
347
348/// Associated functions for building `Bit` instances (with `Unit`).
349impl Bit {
350    /// Create a new `Bit` instance from a size of bits with a unit.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use byte_unit::{Bit, Unit};
356    ///
357    /// let bit = Bit::from_u128_with_unit(15, Unit::Mbit).unwrap(); // 15 Mb
358    /// ```
359    ///
360    /// # Points to Note
361    ///
362    /// * If the calculated bit is too large, this function will return `None`.
363    #[inline]
364    pub const fn from_u128_with_unit(size: u128, unit: Unit) -> Option<Self> {
365        let v = {
366            match unit {
367                Unit::Bit => size,
368                _ => match size.checked_mul(unit.as_bits_u128()) {
369                    Some(v) => v,
370                    None => return None,
371                },
372            }
373        };
374
375        Self::from_u128(v)
376    }
377
378    /// Create a new `Bit` instance from a size of bits with a unit.
379    ///
380    /// # Examples
381    ///
382    /// ```
383    /// use byte_unit::{Bit, Unit};
384    ///
385    /// let bit = Bit::from_u64_with_unit(15, Unit::Mbit).unwrap(); // 15 Mb
386    /// ```
387    ///
388    /// # Points to Note
389    ///
390    /// * If the calculated bit is too large, this function will return `None`.
391    /// * If the input **unit** is `Bit`, the calculated bit will be rounded up.
392    #[inline]
393    pub const fn from_u64_with_unit(size: u64, unit: Unit) -> Option<Self> {
394        #[cfg(feature = "u128")]
395        {
396            Self::from_u128_with_unit(size as u128, unit)
397        }
398
399        #[cfg(not(feature = "u128"))]
400        {
401            let v = {
402                match unit {
403                    Unit::Bit => size,
404                    _ => match size.checked_mul(unit.as_bits_u64()) {
405                        Some(v) => v,
406                        None => return None,
407                    },
408                }
409            };
410
411            Some(Self::from_u64(v))
412        }
413    }
414
415    /// Create a new `Bit` instance from a size of bits with a unit.
416    ///
417    /// # Examples
418    ///
419    /// ```
420    /// use byte_unit::{Bit, Unit};
421    ///
422    /// let bit = Bit::from_f64_with_unit(15.0, Unit::Mbit).unwrap(); // 15 Mb
423    /// ```
424    ///
425    /// # Points to Note
426    ///
427    /// * If the calculated bit is too large or not greater than or equal to **0**, this function will return `None`.
428    /// * The calculated bit will be rounded up.
429    #[inline]
430    pub fn from_f64_with_unit(size: f64, unit: Unit) -> Option<Self> {
431        match Decimal::from_f64(size) {
432            Some(size) => Self::from_decimal_with_unit(size, unit),
433            None => None,
434        }
435    }
436
437    /// Create a new `Bit` instance from a size of bits with a unit.
438    ///
439    /// # Examples
440    ///
441    /// ```
442    /// use byte_unit::{Bit, Unit};
443    ///
444    /// let bit = Bit::from_f32_with_unit(15.0, Unit::Mbit).unwrap(); // 15 Mb
445    /// ```
446    ///
447    /// # Points to Note
448    ///
449    /// * If the calculated bit is too large or not greater than or equal to **0**, this function will return `None`.
450    /// * The calculated bit will be rounded up.
451    #[inline]
452    pub fn from_f32_with_unit(size: f32, unit: Unit) -> Option<Self> {
453        match Decimal::from_f32(size) {
454            Some(size) => Self::from_decimal_with_unit(size, unit),
455            None => None,
456        }
457    }
458
459    /// Create a new `Bit` instance from a size of bits with a unit.
460    ///
461    /// # Examples
462    ///
463    /// ```
464    /// use byte_unit::{Bit, Unit};
465    ///
466    /// let bit = Bit::from_i128_with_unit(15, Unit::Mibit).unwrap(); // 15 Mb
467    /// ```
468    ///
469    /// # Points to Note
470    ///
471    /// * If the calculated bit is too large or negative, this function will return `None`.
472    #[inline]
473    pub const fn from_i128_with_unit(size: i128, unit: Unit) -> Option<Self> {
474        if size >= 0 {
475            Self::from_u128_with_unit(size as u128, unit)
476        } else {
477            None
478        }
479    }
480
481    /// Create a new `Bit` instance from a size of bits with a unit.
482    ///
483    /// # Examples
484    ///
485    /// ```
486    /// use byte_unit::{Bit, Unit};
487    ///
488    /// let bit = Bit::from_i64_with_unit(15, Unit::Mbit).unwrap(); // 15 Mb
489    /// ```
490    ///
491    /// # Points to Note
492    ///
493    /// * If the calculated bit is too large or negative, this function will return `None`.
494    #[inline]
495    pub const fn from_i64_with_unit(size: i64, unit: Unit) -> Option<Self> {
496        if size >= 0 {
497            Self::from_u64_with_unit(size as u64, unit)
498        } else {
499            None
500        }
501    }
502}
503
504/// Methods for converting a `Bit` instance into a primitive integer.
505impl Bit {
506    /// Retrieve the bit represented by this `Bit` instance.
507    ///
508    /// # Examples
509    ///
510    /// ```
511    /// use byte_unit::Bit;
512    ///
513    /// let bit = Bit::parse_str("123KiB").unwrap();
514    ///
515    /// let result = bit.as_u128();
516    ///
517    /// assert_eq!(1007616, result);
518    /// ```
519    ///
520    /// ```
521    /// use byte_unit::Bit;
522    ///
523    /// let bit = Bit::parse_str("123Kib").unwrap();
524    ///
525    /// let result = bit.as_u128();
526    ///
527    /// assert_eq!(125952, result);
528    /// ```
529    #[inline]
530    pub const fn as_u128(self) -> u128 {
531        #[cfg(feature = "u128")]
532        {
533            self.0
534        }
535
536        #[cfg(not(feature = "u128"))]
537        {
538            self.0 as u128
539        }
540    }
541
542    /// Retrieve the bit represented by this `Bit` instance. When the `u128` feature is enabled, if the bit is actually greater than **2<sup>64</sup> - 1**, it will return **2<sup>64</sup> - 1**.
543    ///
544    /// # Examples
545    ///
546    /// ```
547    /// use byte_unit::Bit;
548    ///
549    /// let bit = Bit::parse_str("1kb").unwrap();
550    ///
551    /// let result = bit.as_u64();
552    ///
553    /// assert_eq!(1000, result);
554    /// ```
555    ///
556    /// ```
557    /// # #[cfg(feature = "u128")]
558    /// # {
559    /// use byte_unit::Bit;
560    ///
561    /// let bit = Bit::parse_str("1zb").unwrap();
562    ///
563    /// let result = bit.as_u64();
564    ///
565    /// assert_eq!(u64::MAX, result);
566    /// # }
567    /// ```
568    #[inline]
569    pub const fn as_u64(self) -> u64 {
570        #[cfg(feature = "u128")]
571        {
572            if self.0 <= u64::MAX as u128 {
573                self.0 as u64
574            } else {
575                u64::MAX
576            }
577        }
578
579        #[cfg(not(feature = "u128"))]
580        {
581            self.0
582        }
583    }
584
585    /// Retrieve the bit represented by this `Bit` instance.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use byte_unit::Bit;
591    ///
592    /// let bit = Bit::parse_str("1k").unwrap();
593    ///
594    /// let result = bit.as_u64_checked();
595    ///
596    /// assert_eq!(Some(1000), result);
597    /// ```
598    ///
599    /// ```
600    /// # #[cfg(feature = "u128")]
601    /// # {
602    /// use byte_unit::Bit;
603    ///
604    /// let bit = Bit::parse_str("1zb").unwrap();
605    ///
606    /// let result = bit.as_u64_checked();
607    ///
608    /// assert_eq!(None, result);
609    /// # }
610    /// ```
611    #[inline]
612    pub const fn as_u64_checked(self) -> Option<u64> {
613        #[cfg(feature = "u128")]
614        {
615            if self.0 <= u64::MAX as u128 {
616                Some(self.0 as u64)
617            } else {
618                None
619            }
620        }
621
622        #[cfg(not(feature = "u128"))]
623        {
624            Some(self.0)
625        }
626    }
627}
628
629/// Methods for calculation.
630impl Bit {
631    /// Add another `Bit` instance.
632    ///
633    /// # Examples
634    ///
635    /// ```
636    /// use byte_unit::Bit;
637    ///
638    /// let bit_1 = Bit::from_u64(1024);
639    /// let bit_2 = Bit::from_u64(512);
640    ///
641    /// let bit = bit_1.add(bit_2).unwrap();
642    ///
643    /// assert_eq!(1536, bit.as_u64());
644    /// ```
645    ///
646    /// # Points to Note
647    ///
648    /// * If the calculated bit is too large, this function will return `None`.
649    #[inline]
650    pub const fn add(self, rhs: Bit) -> Option<Bit> {
651        match self.0.checked_add(rhs.0) {
652            Some(v) => Some(Bit(v)),
653            None => None,
654        }
655    }
656
657    /// Subtract another `Bit` instance.
658    ///
659    /// # Examples
660    ///
661    /// ```
662    /// use byte_unit::Bit;
663    ///
664    /// let bit_1 = Bit::from_u64(1024);
665    /// let bit_2 = Bit::from_u64(512);
666    ///
667    /// let bit = bit_1.subtract(bit_2).unwrap();
668    ///
669    /// assert_eq!(512, bit.as_u64());
670    /// ```
671    ///
672    /// # Points to Note
673    ///
674    /// * If the right-hand side is bigger then this `Bit` instance, this function will return `None`.
675    #[inline]
676    pub const fn subtract(self, rhs: Bit) -> Option<Bit> {
677        match self.0.checked_sub(rhs.0) {
678            Some(v) => Some(Bit(v)),
679            None => None,
680        }
681    }
682
683    /// Multiplied by an unsigned integer.
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// use byte_unit::Bit;
689    ///
690    /// let count = 100;
691    /// let bit = Bit::from_u64(1024);
692    ///
693    /// let total_bit = bit.multiply(100).unwrap();
694    ///
695    /// assert_eq!(102400, total_bit.as_u64());
696    /// ```
697    ///
698    /// # Points to Note
699    ///
700    /// * If the calculated bit is too large, this function will return `None`.
701    #[allow(unexpected_cfgs)]
702    #[inline]
703    pub const fn multiply(self, rhs: usize) -> Option<Bit> {
704        #[cfg(feature = "u128")]
705        {
706            match self.0.checked_mul(rhs as u128) {
707                Some(v) => Some(Bit(v)),
708                None => None,
709            }
710        }
711
712        #[cfg(not(feature = "u128"))]
713        {
714            #[cfg(target_pointer_width = "128")]
715            {
716                if rhs > u64::MAX as usize {
717                    return None;
718                }
719            }
720
721            match self.0.checked_mul(rhs as u64) {
722                Some(v) => Some(Bit(v)),
723                None => None,
724            }
725        }
726    }
727
728    /// Divided by an unsigned integer.
729    ///
730    /// # Examples
731    ///
732    /// ```
733    /// use byte_unit::Bit;
734    ///
735    /// let count = 100;
736    /// let bit = Bit::from_u64(1024);
737    ///
738    /// let total_bit = bit.divide(100).unwrap();
739    ///
740    /// assert_eq!(10, total_bit.as_u64());
741    /// ```
742    ///
743    /// # Points to Note
744    ///
745    /// * If the input right-hand side is zero, this function will return `None`.
746    /// * The result will be rounded down.
747    #[allow(unexpected_cfgs)]
748    #[inline]
749    pub const fn divide(self, rhs: usize) -> Option<Bit> {
750        #[cfg(feature = "u128")]
751        {
752            match self.0.checked_div(rhs as u128) {
753                Some(v) => Some(Bit(v)),
754                None => None,
755            }
756        }
757
758        #[cfg(not(feature = "u128"))]
759        {
760            #[cfg(target_pointer_width = "128")]
761            {
762                if rhs > u64::MAX as usize {
763                    return None;
764                }
765            }
766
767            match self.0.checked_div(rhs as u64) {
768                Some(v) => Some(Bit(v)),
769                None => None,
770            }
771        }
772    }
773
774    #[inline]
775    pub(crate) const fn mul_8(self) -> Bit {
776        Bit(self.0 * 8)
777    }
778}
779
780/// Methods for finding an unit.
781impl Bit {
782    /// Obtain the largest unit which is the greatest factor of this `Bit` instance.
783    ///
784    /// # Examples
785    ///
786    /// ```
787    /// use byte_unit::{Bit, Unit};
788    ///
789    /// let bit = Bit::from_u64(3145728);
790    ///
791    /// let (n, unit) = bit.get_exact_unit(true);
792    ///
793    /// assert_eq!(3, n);
794    /// assert_eq!(Unit::Mibit, unit);
795    /// ```
796    ///
797    /// ```
798    /// use byte_unit::{Bit, Unit};
799    ///
800    /// let bit = Bit::from_u64(24000000);
801    ///
802    /// let (n, unit) = bit.get_exact_unit(true);
803    ///
804    /// assert_eq!(3, n);
805    /// assert_eq!(Unit::MB, unit);
806    /// ```
807    ///
808    /// ```
809    /// use byte_unit::{Bit, Unit};
810    ///
811    /// let bit = Bit::from_u64(24000000);
812    ///
813    /// let (n, unit) = bit.get_exact_unit(false);
814    ///
815    /// assert_eq!(24, n);
816    /// assert_eq!(Unit::Mbit, unit);
817    /// ```
818    #[inline]
819    pub const fn get_exact_unit(self, allow_in_bytes: bool) -> (u128, Unit) {
820        let bits_v = self.as_u128();
821
822        let a = if allow_in_bytes { Unit::get_multiples() } else { Unit::get_multiples_bits() };
823        let mut i = a.len() - 1;
824
825        loop {
826            let unit = a[i];
827
828            let unit_v = unit.as_bits_u128();
829
830            if bits_v >= unit_v && bits_v % unit_v == 0 {
831                return (bits_v / unit_v, unit);
832            }
833
834            if i == 0 {
835                break;
836            }
837
838            i -= 1;
839        }
840
841        (bits_v, Unit::Bit)
842    }
843}