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