Description
Feature gate: #![feature(int_log)]
Stabilization report: #70887 (comment)
This is a tracking issue for adding {checked_,}{ilog,ilog2,ilog10}
methods to {u8,u16,u32,u64,u128}
. A full rationale can be found in #80918 (comment). But in short: integer logarithms are fairly common, but require care to implement correctly, and effort to implement efficiently.
Because we expose log
methods for floats it can be tempting for users to use that instead, which can lead to rounding errors. In the following example we're trying to calculate base10
for an integer. We might try and calculate the base2
for the values, and attempt a base swap to arrive at base10
. However because we're performing intermediate rounding we arrive at the wrong result:
// log10(900) = ~2.95 = 2
dbg!(900f32.log10() as u64);
// log base change rule: logb(x) = logc(x) / logc(b)
// log2(900) / log2(10) = 9/3 = 3, which is incorrect!
dbg!((900f32.log2() as u64) / (10f32.log2() as u64));
Public API
// integer log
assert_eq!(5_u16.ilog(5), 1);
assert_eq!(2_u32.ilog2(), 1);
assert_eq!(10_u32.ilog10(), 1);
// checked integer log
assert_eq!(5_u16.checked_ilog(5), Some(1));
assert_eq!(2_u32.checked_ilog2(), Some(1));
<
8000
span class="pl-en">assert_eq!(10_u32.checked_ilog10(), Some(1));
assert_eq!(0_u64.checked_ilog(5), None);
Steps / History
- Implementation: Add Integer::log variants #80918
- Stabilization report Tracking Issue for Integer::{ilog,ilog2,ilog10} #70887 (comment)
- Final comment period (FCP)
Unresolved Questions
- Can we further optimize the
ilog10
implementation? Add Integer::checked_{log,log2,log10} #70835 (comment) - Can we make these methods
const fn
? - Can we implement these types for
NonZero{Int}
? Add Integer::checked_{log,log2,log10} #70835 (comment)- Can we omit returning
Option
forilog2/ilog10
onNonZero{Int}
?
- Can we omit returning
- Should the methods be called
Integer::{ilog,ilog2,ilog10}
instead? Add Integer::checked_{log,log2,log10} #70835 (comment) Tracking Issue for Integer::{ilog,ilog2,ilog10} #70887 (comment)
Implementation History
- Add Integer::checked_{log,log2,log10} #70835 - initial PR, closed due to inactivity
- Add Integer::log variants #80918 - attempt 2 to implement
log
methods, merged - Add
log2
andlog10
toNonZeroU*
#92956 -log
methods forNonZero
types - Rename integer log* methods to ilog* #100332 - rename
log
methods toilog
- Panic for invalid arguments of
{integer primitive}::ilog{,2,10}
in all modes #102578 - panic on invalid args