Skip to content

Commit ed76c11

Browse files
committed
special case for integer log10
1 parent b0f98c6 commit ed76c11

File tree

4 files changed

+144
-3
lines changed

4 files changed

+144
-3
lines changed

library/core/src/num/int_log10.rs

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
mod unchecked {
2+
// 0 < val <= u8::MAX
3+
pub const fn u8(val: u8) -> u32 {
4+
if val >= 100 {
5+
2
6+
} else if val >= 10 {
7+
1
8+
} else {
9+
0
10+
}
11+
}
12+
13+
// 0 < val <= u16::MAX
14+
pub const fn u16(val: u16) -> u32 {
15+
if val >= 10_000 {
16+
4
17+
} else if val >= 1000 {
18+
3
19+
} else if val >= 100 {
20+
2
21+
} else if val >= 10 {
22+
1
23+
} else {
24+
0
25+
}
26+
}
27+
28+
// 0 < val < 100_000_000
29+
const fn less_than_8(mut val: u32) -> u32 {
30+
let mut log = 0;
31+
if val >= 10_000 {
32+
val /= 10_000;
33+
log += 4;
34+
}
35+
log + if val >= 1000 {
36+
3
37+
} else if val >= 100 {
38+
2
39+
} else if val >= 10 {
40+
1
41+
} else {
42+
0
43+
}
44+
}
45+
46+
// 0 < val <= u32::MAX
47+
pub const fn u32(mut val: u32) -> u32 {
48+
let mut log = 0;
49+
if val >= 100_000_000 {
50+
val /= 100_000_000;
51+
log += 8;
52+
}
53+
log + less_than_8(val)
54+
}
55+
56+
// 0 < val < 10_000_000_000_000_000
57+
const fn less_than_16(mut val: u64) -> u32 {
58+
let mut log = 0;
59+
if val >= 100_000_000 {
60+
val /= 100_000_000;
61+
log += 8;
62+
}
63+
log + less_than_8(val as u32)
64+
}
65+
66+
// 0 < val <= u64::MAX
67+
pub const fn u64(mut val: u64) -> u32 {
68+
let mut log = 0;
69+
if val >= 10_000_000_000_000_000 {
70+
val /= 10_000_000_000_000_000;
71+
log += 16;
72+
}
73+
log + less_than_16(val)
74+
}
75+
76+
// 0 < val <= u128::MAX
77+
pub const fn u128(mut val: u128) -> u32 {
78+
let mut log = 0;
79+
if val >= 100_000_000_000_000_000_000_000_000_000_000 {
80+
val /= 100_000_000_000_000_000_000_000_000_000_000;
81+
log += 32;
82+
return log + less_than_8(val as u32);
83+
}
84+
if val >= 10_000_000_000_000_000 {
85+
val /= 10_000_000_000_000_000;
86+
log += 16;
87+
}
88+
log + less_than_16(val as u64)
89+
}
90+
91+
// 0 < val <= i8::MAX
92+
pub const fn i8(val: i8) -> u32 {
93+
u8(val as u8)
94+
}
95+
96+
// 0 < val <= i16::MAX
97+
pub const fn i16(val: i16) -> u32 {
98+
u16(val as u16)
99+
}
100+
101+
// 0 < val <= i32::MAX
102+
pub const fn i32(val: i32) -> u32 {
103+
u32(val as u32)
104+
}
105+
106+
// 0 < val <= i64::MAX
107+
pub const fn i64(val: i64) -> u32 {
108+
u64(val as u64)
109+
}
110+
111+
// 0 < val <= i128::MAX
112+
pub const fn i128(val: i128) -> u32 {
113+
u128(val as u128)
114+
}
115+
}
116+
117+
macro_rules! impl_checked {
118+
($T:ident) => {
119+
pub const fn $T(val: $T) -> Option<$T> {
120+
if val > 0 { Some(unchecked::$T(val) as $T) } else { None }
121+
}
122+
};
123+
}
124+
125+
impl_checked! { u8 }
126+
impl_checked! { u16 }
127+
impl_checked! { u32 }
128+
impl_checked! { u64 }
129+
impl_checked! { u128 }
130+
impl_checked! { i8 }
131+
impl_checked! { i16 }
132+
impl_checked! { i32 }
133+
impl_checked! { i64 }
134+
impl_checked! { i128 }

library/core/src/num/int_macros.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,10 @@ macro_rules! int_impl {
19291929
without modifying the original"]
19301930
#[inline]
19311931
pub const fn checked_log10(self) -> Option<Self> {
1932-
self.checked_log(10)
1932+
match int_log10::$ActualT(self as $ActualT) {
1933+
Some(s) => Some(s as Self),
1934+
None => None,
1935+
}
19331936
}
19341937

19351938
/// Computes the absolute value of `self`.

library/core/src/num/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ mod int_macros; // import int_impl!
4141
mod uint_macros; // import uint_impl!
4242

4343
mod error;
44+
mod int_log10;
4445
mod nonzero;
4546
mod wrapping;
4647

library/core/src/num/uint_macros.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro_rules! uint_impl {
2-
($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr,
2+
($SelfT:ty, $ActualT:ident, $BITS:expr, $MaxV:expr,
33
$rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
44
$reversed:expr, $le_bytes:expr, $be_bytes:expr,
55
$to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
@@ -819,7 +819,10 @@ macro_rules! uint_impl {
819819
without modifying the original"]
820820
#[inline]
821821
pub const fn checked_log10(self) -> Option<Self> {
822-
self.checked_log(10)
822+
match int_log10::$ActualT(self as $ActualT) {
823+
Some(s) => Some(s as Self),
824+
None => None,
825+
}
823826
}
824827

825828
/// Checked negation. Computes `-self`, returning `None` unless `self ==

0 commit comments

Comments
 (0)