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}