add int_log10 and checked_int_log10
This commit is contained in:
parent
919519fea1
commit
a32b56ab43
26
README.md
26
README.md
|
@ -76,15 +76,18 @@ The conversions supported cover the following cases.
|
|||
|
||||
### Version 0.5.5 news (unreleased)
|
||||
|
||||
* The associated constants [`MIN`] and [`MAX`] were added to all
|
||||
fixed-point types, to the [`Fixed`] trait, and to the [`Wrapping`]
|
||||
wrapper.
|
||||
* The associated constants [`INT_NBITS`] and [`FRAC_NBITS`] were
|
||||
added to the [`Fixed`] trait and to the [`Wrapping`] wrapper.
|
||||
* The methods [`int_log2`] and [`checked_int_log2`] were added to
|
||||
all fixed-point types and to the [`Fixed`] trait.
|
||||
* The method [`int_log2`][wril] was added to the [`Wrapping`]
|
||||
wrapper.
|
||||
* The following associated constants were added to all fixed-point
|
||||
types, to the [`Fixed`] trait, and to the [`Wrapping`] wrapper:
|
||||
* [`MIN`], [`MAX`]
|
||||
* The following associated constants were added to the [`Fixed`]
|
||||
trait and to the [`Wrapping`] wrapper:
|
||||
* [`INT_NBITS`], [`FRAC_NBITS`]
|
||||
* The following methods were added to all fixed-point types and to
|
||||
the [`Fixed`] trait:
|
||||
* [`int_log2`], [`int_log10`]
|
||||
* [`checked_int_log2`], [`checked_int_log10`]
|
||||
* The following methods were added to the [`Wrapping`] wrapper:
|
||||
* [`int_log2`][wril2], [`int_log10`][wril10]
|
||||
* The following methods were deprecated:
|
||||
* [`min_value`], [`max_value`]
|
||||
* [`int_nbits`][`int_nbits()`], [`frac_nbits`][`frac_nbits()`]
|
||||
|
@ -131,11 +134,13 @@ The conversions supported cover the following cases.
|
|||
[`Rem`]: https://doc.rust-lang.org/nightly/core/ops/trait.Rem.html
|
||||
[`Wrapping`]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html
|
||||
[`checked_div_euclid`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.checked_div_euclid
|
||||
[`checked_int_log10`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.checked_int_log10
|
||||
[`checked_int_log2`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.checked_int_log2
|
||||
[`checked_rem_euclid`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.checked_rem_euclid
|
||||
[`checked_rem`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.checked_rem
|
||||
[`div_euclid`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.div_euclid
|
||||
[`frac_nbits()`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.frac_nbits
|
||||
[`int_log10`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.int_log10
|
||||
[`int_log2`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.int_log2
|
||||
[`int_nbits()`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.int_nbits
|
||||
[`max_value`]: https://docs.rs/fixed/0.5.4/fixed/struct.FixedI32.html#method.max_value
|
||||
|
@ -153,7 +158,8 @@ The conversions supported cover the following cases.
|
|||
[wdei]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html#method.div_euclid_int
|
||||
[wre]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html#method.rem_euclid
|
||||
[wrei]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html#method.rem_euclid_int
|
||||
[wril]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html#method.int_log2
|
||||
[wril10]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html#method.int_log10
|
||||
[wril2]: https://docs.rs/fixed/0.5.4/fixed/struct.Wrapping.html#method.int_log2
|
||||
|
||||
### Other releases
|
||||
|
||||
|
|
20
RELEASES.md
20
RELEASES.md
|
@ -8,14 +8,18 @@ as-is, without any warranty. -->
|
|||
Version 0.5.5 (unreleased)
|
||||
==========================
|
||||
|
||||
* The associated constants `MIN` and `MAX` were added to all
|
||||
fixed-point types, to the `Fixed` trait, and to the `Wrapping`
|
||||
wrapper.
|
||||
* The associated constants `INT_NBITS` and `FRAC_NBITS` were added
|
||||
to the `Fixed` trait and to the `Wrapping` wrapper.
|
||||
* The methods `int_log2` and `checked_int_log2` were added to all
|
||||
fixed-point types and to the `Fixed` trait.
|
||||
* The method `int_log2` was added to the `Wrapping` wrapper.
|
||||
* The following associated constants were added to all fixed-point
|
||||
types, to the `Fixed` trait, and to the `Wrapping` wrapper:
|
||||
* `MIN`, `MAX`
|
||||
* The following associated constants were added to the `Fixed` trait
|
||||
and to the `Wrapping` wrapper:
|
||||
* `INT_NBITS`, `FRAC_NBITS`
|
||||
* The following methods were added to all fixed-point types and to
|
||||
the `Fixed` trait:
|
||||
* `int_log2`, `int_log10`
|
||||
* `checked_int_log2`, `checked_int_log10`
|
||||
* The following methods were added to the `Wrapping` wrapper:
|
||||
* `int_log2`, `int_log10`
|
||||
* The following methods were deprecated:
|
||||
* `min_value`, `max_value`
|
||||
* `int_nbits`, `frac_nbits`
|
||||
|
|
|
@ -261,6 +261,7 @@ mod float_helper;
|
|||
mod from_str;
|
||||
mod helpers;
|
||||
mod int_helper;
|
||||
mod log10;
|
||||
#[cfg(feature = "serde")]
|
||||
mod serdeize;
|
||||
pub mod traits;
|
||||
|
@ -273,6 +274,7 @@ use crate::{
|
|||
from_str::FromStrRadix,
|
||||
traits::{FromFixed, ToFixed},
|
||||
types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8},
|
||||
log10::IntFracLog10,
|
||||
};
|
||||
pub use crate::{from_str::ParseFixedError, wrapping::Wrapping};
|
||||
use core::{
|
||||
|
|
|
@ -0,0 +1,376 @@
|
|||
// Copyright © 2018–2019 Trevor Spiteri
|
||||
|
||||
// This library is free software: you can redistribute it and/or
|
||||
// modify it under the terms of either
|
||||
//
|
||||
// * the Apache License, Version 2.0 or
|
||||
// * the MIT License
|
||||
//
|
||||
// at your option.
|
||||
//
|
||||
// You should have recieved copies of the Apache License and the MIT
|
||||
// License along with the library. If not, see
|
||||
// <https://www.apache.org/licenses/LICENSE-2.0> and
|
||||
// <https://opensource.org/licenses/MIT>.
|
||||
|
||||
// self must be positive
|
||||
pub trait IntFracLog10 {
|
||||
fn int_part_log10(self) -> i32;
|
||||
fn frac_part_log10(self) -> i32;
|
||||
}
|
||||
|
||||
impl IntFracLog10 for u8 {
|
||||
#[inline]
|
||||
fn int_part_log10(self) -> i32 {
|
||||
if self >= 100 {
|
||||
2
|
||||
} else if self >= 10 {
|
||||
1
|
||||
} else {
|
||||
debug_assert!(self >= 1);
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn frac_part_log10(self) -> i32 {
|
||||
if self > 25 {
|
||||
-1
|
||||
} else if self > 2 {
|
||||
-2
|
||||
} else {
|
||||
debug_assert!(self > 0);
|
||||
-3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntFracLog10 for u16 {
|
||||
#[inline]
|
||||
fn int_part_log10(self) -> i32 {
|
||||
if self >= 10_000 {
|
||||
4
|
||||
} else if self >= 1000 {
|
||||
3
|
||||
} else if self >= 100 {
|
||||
2
|
||||
} else if self >= 10 {
|
||||
1
|
||||
} else {
|
||||
debug_assert!(self >= 1);
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn frac_part_log10(self) -> i32 {
|
||||
if self > 6553 {
|
||||
-1
|
||||
} else if self > 655 {
|
||||
-2
|
||||
} else if self > 65 {
|
||||
-3
|
||||
} else if self > 6 {
|
||||
-4
|
||||
} else {
|
||||
debug_assert!(self > 0);
|
||||
-5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn int_part_log10_less_than_8(mut i: u32) -> i32 {
|
||||
debug_assert!(i < 100_000_000);
|
||||
let mut log = 0;
|
||||
if i >= 10_000 {
|
||||
i /= 10_000;
|
||||
log += 4;
|
||||
}
|
||||
log + if i >= 1000 {
|
||||
3
|
||||
} else if i >= 100 {
|
||||
2
|
||||
} else if i >= 10 {
|
||||
1
|
||||
} else {
|
||||
debug_assert!(i >= 1);
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl IntFracLog10 for u32 {
|
||||
fn int_part_log10(mut self) -> i32 {
|
||||
let mut log = 0;
|
||||
if self >= 100_000_000 {
|
||||
self /= 100_000_000;
|
||||
log += 8;
|
||||
}
|
||||
log + int_part_log10_less_than_8(self)
|
||||
}
|
||||
|
||||
fn frac_part_log10(mut self) -> i32 {
|
||||
const MAX: u32 = u32::max_value();
|
||||
let mut log = 0;
|
||||
if self <= MAX / 100_000_000 {
|
||||
self *= 100_000_000;
|
||||
log += -8;
|
||||
}
|
||||
if self <= MAX / 10_000 {
|
||||
self *= 10_000;
|
||||
log += -4;
|
||||
}
|
||||
log + if self > MAX / 10 {
|
||||
-1
|
||||
} else if self > MAX / 100 {
|
||||
-2
|
||||
} else if self > MAX / 1000 {
|
||||
-3
|
||||
} else {
|
||||
debug_assert!(self > MAX / 10_000);
|
||||
-4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn int_part_log10_less_than_16(mut i: u64) -> i32 {
|
||||
debug_assert!(i < 10_000_000_000_000_000);
|
||||
let mut log = 0;
|
||||
if i >= 100_000_000 {
|
||||
i /= 100_000_000;
|
||||
log += 8;
|
||||
}
|
||||
debug_assert_eq!(i >> 32, 0);
|
||||
log + int_part_log10_less_than_8(i as u32)
|
||||
}
|
||||
|
||||
impl IntFracLog10 for u64 {
|
||||
fn int_part_log10(mut self) -> i32 {
|
||||
let mut log = 0;
|
||||
if self >= 10_000_000_000_000_000 {
|
||||
self /= 10_000_000_000_000_000;
|
||||
log += 16;
|
||||
}
|
||||
log + int_part_log10_less_than_16(self)
|
||||
}
|
||||
|
||||
fn frac_part_log10(mut self) -> i32 {
|
||||
const MAX: u64 = u64::max_value();
|
||||
let mut log = 0;
|
||||
if self <= MAX / 10_000_000_000_000_000 {
|
||||
log += -16;
|
||||
self *= 10_000_000_000_000_000;
|
||||
}
|
||||
if self <= MAX / 100_000_000 {
|
||||
log += -8;
|
||||
self *= 100_000_000;
|
||||
}
|
||||
if self <= MAX / 10_000 {
|
||||
log += -4;
|
||||
self *= 10_000;
|
||||
}
|
||||
log + if self > MAX / 10 {
|
||||
-1
|
||||
} else if self > MAX / 100 {
|
||||
-2
|
||||
} else if self > MAX / 1000 {
|
||||
-3
|
||||
} else {
|
||||
debug_assert!(self > MAX / 10_000);
|
||||
-4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntFracLog10 for u128 {
|
||||
fn int_part_log10(mut self) -> i32 {
|
||||
let mut log = 0;
|
||||
if self >= 100_000_000_000_000_000_000_000_000_000_000 {
|
||||
self /= 100_000_000_000_000_000_000_000_000_000_000;
|
||||
log += 32;
|
||||
}
|
||||
if self >= 10_000_000_000_000_000 {
|
||||
self /= 10_000_000_000_000_000;
|
||||
log += 16;
|
||||
}
|
||||
debug_assert_eq!(self >> 64, 0);
|
||||
log + int_part_log10_less_than_16(self as u64)
|
||||
}
|
||||
|
||||
fn frac_part_log10(mut self) -> i32 {
|
||||
const MAX: u128 = u128::max_value();
|
||||
let mut log = 0;
|
||||
if self <= MAX / 100_000_000_000_000_000_000_000_000_000_000 {
|
||||
log += -32;
|
||||
self *= 100_000_000_000_000_000_000_000_000_000_000;
|
||||
}
|
||||
if self <= MAX / 10_000_000_000_000_000 {
|
||||
log += -16;
|
||||
self *= 10_000_000_000_000_000;
|
||||
}
|
||||
if self <= MAX / 100_000_000 {
|
||||
log += -8;
|
||||
self *= 100_000_000;
|
||||
}
|
||||
if self <= MAX / 10_000 {
|
||||
log += -4;
|
||||
self *= 10_000;
|
||||
}
|
||||
log + if self > MAX / 10 {
|
||||
-1
|
||||
} else if self > MAX / 100 {
|
||||
-2
|
||||
} else if self > MAX / 1000 {
|
||||
-3
|
||||
} else {
|
||||
debug_assert!(self > MAX / 10_000);
|
||||
-4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::IntFracLog10;
|
||||
|
||||
#[test]
|
||||
fn int_part_log10_u8() {
|
||||
assert_eq!(u8::max_value().int_part_log10(), 2);
|
||||
for i in 0..=2 {
|
||||
let p = 10u8.pow(i as u32);
|
||||
if i > 0 {
|
||||
assert_eq!((p - 1).int_part_log10(), i - 1);
|
||||
}
|
||||
assert_eq!(p.int_part_log10(), i);
|
||||
assert_eq!((p + 1).int_part_log10(), i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn frac_part_log10_u8() {
|
||||
assert_eq!(1u8.frac_part_log10(), -3);
|
||||
for i in 0..=2 {
|
||||
let p = u8::max_value() / 10u8.pow(i as u32);
|
||||
if p > 1 {
|
||||
assert_eq!((p - 1).frac_part_log10(), -1 - i);
|
||||
}
|
||||
assert_eq!(p.frac_part_log10(), -1 - i);
|
||||
if i > 0 {
|
||||
assert_eq!((p + 1).frac_part_log10(), -i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_part_log10_u16() {
|
||||
assert_eq!(u16::max_value().int_part_log10(), 4);
|
||||
for i in 0..=4 {
|
||||
let p = 10u16.pow(i as u32);
|
||||
if i > 0 {
|
||||
assert_eq!((p - 1).int_part_log10(), i - 1);
|
||||
}
|
||||
assert_eq!(p.int_part_log10(), i);
|
||||
assert_eq!((p + 1).int_part_log10(), i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn frac_part_log10_u16() {
|
||||
assert_eq!(1u16.frac_part_log10(), -5);
|
||||
for i in 0..=4 {
|
||||
let p = u16::max_value() / 10u16.pow(i as u32);
|
||||
if p > 1 {
|
||||
assert_eq!((p - 1).frac_part_log10(), -1 - i);
|
||||
}
|
||||
assert_eq!(p.frac_part_log10(), -1 - i);
|
||||
if i > 0 {
|
||||
assert_eq!((p + 1).frac_part_log10(), -i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_part_log10_u32() {
|
||||
assert_eq!(u32::max_value().int_part_log10(), 9);
|
||||
for i in 0..=9 {
|
||||
let p = 10u32.pow(i as u32);
|
||||
if i > 0 {
|
||||
assert_eq!((p - 1).int_part_log10(), i - 1);
|
||||
}
|
||||
assert_eq!(p.int_part_log10(), i);
|
||||
assert_eq!((p + 1).int_part_log10(), i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn frac_part_log10_u32() {
|
||||
assert_eq!(1u32.frac_part_log10(), -10);
|
||||
for i in 0..=9 {
|
||||
let p = u32::max_value() / 10u32.pow(i as u32);
|
||||
if p > 1 {
|
||||
assert_eq!((p - 1).frac_part_log10(), -1 - i);
|
||||
}
|
||||
assert_eq!(p.frac_part_log10(), -1 - i);
|
||||
if i > 0 {
|
||||
assert_eq!((p + 1).frac_part_log10(), -i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_part_log10_u64() {
|
||||
assert_eq!(u64::max_value().int_part_log10(), 19);
|
||||
for i in 0..=19 {
|
||||
let p = 10u64.pow(i as u32);
|
||||
if i > 0 {
|
||||
assert_eq!((p - 1).int_part_log10(), i - 1);
|
||||
}
|
||||
assert_eq!(p.int_part_log10(), i);
|
||||
assert_eq!((p + 1).int_part_log10(), i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn frac_part_log10_u64() {
|
||||
assert_eq!(1u64.frac_part_log10(), -20);
|
||||
for i in 0..=19 {
|
||||
let p = u64::max_value() / 10u64.pow(i as u32);
|
||||
if p > 1 {
|
||||
assert_eq!((p - 1).frac_part_log10(), -1 - i);
|
||||
}
|
||||
assert_eq!(p.frac_part_log10(), -1 - i);
|
||||
if i > 0 {
|
||||
assert_eq!((p + 1).frac_part_log10(), -i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_part_log10_u128() {
|
||||
assert_eq!(u128::max_value().int_part_log10(), 38);
|
||||
for i in 0..=38 {
|
||||
let p = 10u128.pow(i as u32);
|
||||
if i > 0 {
|
||||
assert_eq!((p - 1).int_part_log10(), i - 1);
|
||||
}
|
||||
assert_eq!(p.int_part_log10(), i);
|
||||
assert_eq!((p + 1).int_part_log10(), i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn frac_part_log10_u128() {
|
||||
assert_eq!(1u128.frac_part_log10(), -39);
|
||||
for i in 0..=38 {
|
||||
let p = u128::max_value() / 10u128.pow(i as u32);
|
||||
if p > 1 {
|
||||
assert_eq!((p - 1).frac_part_log10(), -1 - i);
|
||||
}
|
||||
assert_eq!(p.frac_part_log10(), -1 - i);
|
||||
if i > 0 {
|
||||
assert_eq!((p + 1).frac_part_log10(), -i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,6 +90,32 @@ assert_eq!(Fix::from_num(0.1875).int_log2(), -3);
|
|||
}
|
||||
}
|
||||
|
||||
comment! {
|
||||
"Integer base-10 logarithm, rounded down.
|
||||
|
||||
# Panics
|
||||
|
||||
Panics if the fixed-point number is ", if_signed_unsigned!($Signedness, "≤ 0", "zero"), ".
|
||||
|
||||
# Examples
|
||||
|
||||
```rust
|
||||
use fixed::{
|
||||
types::extra::{U2, U6},
|
||||
", $s_fixed, ",
|
||||
};
|
||||
assert_eq!(", $s_fixed, "::<U2>::from_num(10).int_log10(), 1);
|
||||
assert_eq!(", $s_fixed, "::<U2>::from_num(9.75).int_log10(), 0);
|
||||
assert_eq!(", $s_fixed, "::<U6>::from_num(0.109375).int_log10(), -1);
|
||||
assert_eq!(", $s_fixed, "::<U6>::from_num(0.09375).int_log10(), -2);
|
||||
```
|
||||
";
|
||||
#[inline]
|
||||
pub fn int_log10(self) -> i32 {
|
||||
self.checked_int_log10().expect("log of non-positive number")
|
||||
}
|
||||
}
|
||||
|
||||
comment! {
|
||||
"Checked integer base-2 logarithm, rounded down.
|
||||
Returns the logarithm or [`None`] if the fixed-point number is
|
||||
|
@ -119,6 +145,45 @@ assert_eq!(Fix::from_num(0.1875).checked_int_log2(), Some(-3));
|
|||
}
|
||||
}
|
||||
|
||||
// TODO when rustc requirement >= 1.43.0, use MAX instead of max_value()
|
||||
comment! {
|
||||
"Checked integer base-10 logarithm, rounded down.
|
||||
Returns the logarithm or [`None`] if the fixed-point number is
|
||||
", if_signed_unsigned!($Signedness, "≤ 0", "zero"), ".
|
||||
|
||||
# Examples
|
||||
|
||||
```rust
|
||||
use fixed::{
|
||||
types::extra::{U2, U6},
|
||||
", $s_fixed, ",
|
||||
};
|
||||
assert_eq!(", $s_fixed, "::<U2>::from_num(0).checked_int_log10(), None);
|
||||
assert_eq!(", $s_fixed, "::<U2>::from_num(10).checked_int_log10(), Some(1));
|
||||
assert_eq!(", $s_fixed, "::<U2>::from_num(9.75).checked_int_log10(), Some(0));
|
||||
assert_eq!(", $s_fixed, "::<U6>::from_num(0.109375).checked_int_log10(), Some(-1));
|
||||
assert_eq!(", $s_fixed, "::<U6>::from_num(0.09375).checked_int_log10(), Some(-2));
|
||||
```
|
||||
|
||||
[`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
|
||||
";
|
||||
#[inline]
|
||||
pub fn checked_int_log10(self) -> Option<i32> {
|
||||
if self <= 0 {
|
||||
return None;
|
||||
}
|
||||
// Use unsigned representation because we use all bits in fractional part.
|
||||
let bits = self.to_bits() as $UInner;
|
||||
let int = bits >> Self::FRAC_NBITS;
|
||||
if int != 0 {
|
||||
Some(int.int_part_log10())
|
||||
} else {
|
||||
let frac = bits << Self::INT_NBITS;
|
||||
Some(frac.frac_part_log10())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_signed! {
|
||||
$Signedness;
|
||||
comment! {
|
||||
|
|
|
@ -621,12 +621,25 @@ where
|
|||
/// Panics if the fixed-point number is ≤ 0.
|
||||
fn int_log2(self) -> i32;
|
||||
|
||||
/// Integer base-10 logarithm, rounded down.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the fixed-point number is ≤ 0.
|
||||
fn int_log10(self) -> i32;
|
||||
|
||||
/// Checked integer base-2 logarithm, rounded down. Returns the
|
||||
/// logarithm or [`None`] if the fixed-point number is ≤ 0.
|
||||
///
|
||||
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
|
||||
fn checked_int_log2(self) -> Option<i32>;
|
||||
|
||||
/// Checked integer base-10 logarithm, rounded down. Returns the
|
||||
/// logarithm or [`None`] if the fixed-point number is ≤ 0.
|
||||
///
|
||||
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
|
||||
fn checked_int_log10(self) -> Option<i32>;
|
||||
|
||||
/// Shifts to the left by `n` bits, wrapping the truncated bits to the right end.
|
||||
fn rotate_left(self, n: u32) -> Self;
|
||||
|
||||
|
@ -1867,7 +1880,9 @@ macro_rules! impl_fixed {
|
|||
trait_delegate! { fn leading_zeros(self) -> u32 }
|
||||
trait_delegate! { fn trailing_zeros(self) -> u32 }
|
||||
trait_delegate! { fn int_log2(self) -> i32 }
|
||||
trait_delegate! { fn int_log10(self) -> i32 }
|
||||
trait_delegate! { fn checked_int_log2(self) -> Option<i32> }
|
||||
trait_delegate! { fn checked_int_log10(self) -> Option<i32> }
|
||||
trait_delegate! { fn rotate_left(self, n: u32) -> Self }
|
||||
trait_delegate! { fn rotate_right(self, n: u32) -> Self }
|
||||
trait_delegate! { fn div_euclid(self, rhs: Self) -> Self }
|
||||
|
|
|
@ -501,6 +501,16 @@ impl<F: Fixed> Wrapping<F> {
|
|||
self.0.int_log2()
|
||||
}
|
||||
|
||||
/// Integer base-10 logarithm, rounded down.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the fixed-point number is ≤ 0.
|
||||
#[inline]
|
||||
pub fn int_log10(self) -> i32 {
|
||||
self.0.int_log10()
|
||||
}
|
||||
|
||||
/// Shifts to the left by `n` bits, wrapping the truncated bits to the right end.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
Loading…
Reference in New Issue