add constants in consts module as associated constants

This commit is contained in:
Trevor Spiteri 2020-04-16 23:08:29 +02:00
parent 68c0fa6f8d
commit 289f4b1697
4 changed files with 306 additions and 98 deletions

View File

@ -89,6 +89,9 @@ The conversions supported cover the following cases.
the [`Fixed`] trait:
* [`int_log2`], [`int_log10`]
* [`checked_int_log2`], [`checked_int_log10`]
* The constants inside the [`consts`] module are now also available
as associated constants when they are representable by a
fixed-point number.
* The following methods were added to the [`Wrapping`] wrapper:
* [`int_log2`][wril2], [`int_log10`][wril10]
* The following methods were deprecated:
@ -141,6 +144,7 @@ The conversions supported cover the following cases.
[`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
[`consts`]: https://docs.rs/fixed/0.5.4/fixed/consts/index.html
[`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

View File

@ -17,6 +17,9 @@ Version 0.5.5 (unreleased)
* The following associated constants were added to the `Fixed` trait
and to the `Wrapping` wrapper:
* `INT_NBITS`, `FRAC_NBITS`
* The constants inside the `consts` module are now also available as
associated constants when they are representable by a fixed-point
number.
* The following methods were added to all fixed-point types and to
the `Fixed` trait:
* `int_log2`, `int_log10`

View File

@ -274,7 +274,11 @@ use crate::{
from_str::FromStrRadix,
log10::IntFracLog10,
traits::{FromFixed, ToFixed},
types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8},
types::extra::{
IsLessOrEqual, LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8, True, Unsigned, U12, U124,
U125, U126, U127, U128, U13, U14, U15, U16, U28, U29, U30, U31, U32, U4, U5, U6, U60, U61,
U62, U63, U64, U7, U8,
},
};
pub use crate::{from_str::ParseFixedError, wrapping::Wrapping};
use core::{
@ -317,22 +321,30 @@ mod macros_const;
macro_rules! fixed {
(
$description:expr,
$Fixed:ident($Inner:ty, $LeEqU:tt, $s_nbits:expr, $s_nbits_m4:expr),
$Fixed:ident(
$Inner:ty, $LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UInner:ty, $Signedness:tt,
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt
) => {
fixed! {
$description,
$Fixed[stringify!($Fixed)]($Inner[stringify!($Inner)], $LeEqU, $s_nbits, $s_nbits_m4),
$Fixed[stringify!($Fixed)](
$Inner[stringify!($Inner)], $LeEqU, $s_nbits,
$s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4
),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$UInner, $Signedness
$UInner, $Signedness,
$LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3
}
};
(
$description:expr,
$Fixed:ident[$s_fixed:expr](
$Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr, $s_nbits_m4:expr
$Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UInner:ty, $Signedness:tt,
@ -414,92 +426,94 @@ assert_eq!(two_point_75.to_string(), \"2.8\");
$UInner, $Signedness
}
fixed_const! {
$Fixed[$s_fixed]($LeEqU, $LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3)
$Fixed[$s_fixed]($LeEqU, $s_nbits, $s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4),
$LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3,
$Signedness
}
};
}
fixed! {
"An eight-bit fixed-point unsigned",
FixedU8(u8, LeEqU8, "8", "4"),
FixedU8(u8, LeEqU8, "8", "7", "6", "5", "4"),
1, "0x12", "[0x12]", "[0x12]",
u8, Unsigned,
LeEqU8, LeEqU7, LeEqU6, LeEqU5
U8, U7, U6, U5
}
fixed! {
"A 16-bit fixed-point unsigned",
FixedU16(u16, LeEqU16, "16", "12"),
FixedU16(u16, LeEqU16, "16", "15", "14", "13", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
u16, Unsigned,
LeEqU16, LeEqU15, LeEqU14, LeEqU13
U16, U15, U14, U13
}
fixed! {
"A 32-bit fixed-point unsigned",
FixedU32(u32, LeEqU32, "32", "28"),
FixedU32(u32, LeEqU32, "32", "31", "30", "29", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
u32, Unsigned,
LeEqU32, LeEqU31, LeEqU30, LeEqU29
U32, U31, U30, U29
}
fixed! {
"A 64-bit fixed-point unsigned",
FixedU64(u64, LeEqU64, "64", "60"),
FixedU64(u64, LeEqU64, "64", "63", "62", "61", "60"),
8, "0x1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
u64, Unsigned,
LeEqU64, LeEqU63, LeEqU62, LeEqU61
U64, U63, U62, U61
}
fixed! {
"A 128-bit fixed-point unsigned",
FixedU128(u128, LeEqU128, "128", "124"),
FixedU128(u128, LeEqU128, "128", "127", "126", "125", "124"),
16, "0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, \
0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
u128, Unsigned,
LeEqU128, LeEqU127, LeEqU126, LeEqU125
U128, U127, U126, U125
}
fixed! {
"An eight-bit fixed-point signed",
FixedI8(i8, LeEqU8, "8", "4"),
FixedI8(i8, LeEqU8, "8", "7", "6", "5", "4"),
1, "0x12", "[0x12]", "[0x12]",
u8, Signed,
LeEqU7, LeEqU6, LeEqU5, LeEqU4
U7, U6, U5, U4
}
fixed! {
"A 16-bit fixed-point signed",
FixedI16(i16, LeEqU16, "16", "12"),
FixedI16(i16, LeEqU16, "16", "15", "14", "13", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
u16, Signed,
LeEqU15, LeEqU14, LeEqU13, LeEqU12
U15, U14, U13, U12
}
fixed! {
"A 32-bit fixed-point signed",
FixedI32(i32, LeEqU32, "32", "28"),
FixedI32(i32, LeEqU32, "32", "31", "30", "29", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
u32, Signed,
LeEqU31, LeEqU30, LeEqU29, LeEqU28
U31, U30, U29, U28
}
fixed! {
"A 64-bit fixed-point signed",
FixedI64(i64, LeEqU64, "64", "60"),
FixedI64(i64, LeEqU64, "64", "63", "62", "61", "60"),
8, "0x1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
u64, Signed,
LeEqU63, LeEqU62, LeEqU61, LeEqU60
U63, U62, U61, U60
}
fixed! {
"A 128-bit fixed-point signed",
FixedI128(i128, LeEqU128, "128", "124"),
FixedI128(i128, LeEqU128, "128", "127", "126", "125", "124"),
16, "0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, \
0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
u128, Signed,
LeEqU127, LeEqU126, LeEqU125, LeEqU124
U127, U126, U125, U124
}
#[cfg(test)]

View File

@ -13,116 +13,303 @@
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.
// split shift in two parts in case it is equal to 128
macro_rules! split {
($CONST:ident >> (128 - $frac:expr)) => {
consts::$CONST >> (64 - $frac / 2) >> (64 + $frac / 2 - $frac)
macro_rules! shift {
// in case of 128, split shift in two parts to avoid >> 128
($SRC:ident, $Fixed:ident<$Frac:ident>) => {
$Fixed::<$Frac>::from_bits(
(consts::$SRC.to_bits() >> (64 - $Frac::U32 / 2) >> (64 + $Frac::U32 / 2 - $Frac::U32))
as _,
)
};
($SRC:ident, $src_frac_nbits:literal, $Fixed:ident<$Frac:ident>) => {
$Fixed::<$Frac>::from_bits((consts::$SRC.to_bits() >> ($src_frac_nbits - $Frac::U32)) as _)
};
}
macro_rules! fixed_const {
(
$Fixed:ident[$s_fixed:expr](
$LeEqU:tt, $LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt
)
$LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt,
$Signedness:tt
) => {
// 0 ≤ constant < 0.5
impl<Frac: $LeEqU> $Fixed<Frac> {
/// 1/τ = 0.159154…
pub const FRAC_1_TAU: U0F128 = split!(consts::FRAC_1_TAU >> (128 - Frac::U32));
comment! {
"This block contains constants in the range 0  <i>x</i> < 0.5.
/// 2/τ = 0.318309…
pub const FRAC_2_TAU: U0F128 = split!(consts::FRAC_2_TAU >> (128 - Frac::U32));
# Examples
/// π/8 = 0.392699…
pub const FRAC_PI_8: U0F128 = split!(consts::FRAC_PI_8 >> (128 - Frac::U32));
```rust
use fixed::{consts, types::extra::U", $s_nbits, ", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U", $s_nbits, ">;
assert_eq!(Fix::LOG10_2, Fix::from_num(consts::LOG10_2));
```
";
impl<Frac: $LeEqU> $Fixed<Frac> {
/// 1/τ = 0.159154…
pub const FRAC_1_TAU: $Fixed<Frac> = shift!(FRAC_1_TAU, $Fixed<Frac>);
/// 1/π = 0.318309…
pub const FRAC_1_PI: U0F128 = split!(consts::FRAC_1_PI >> (128 - Frac::U32));
/// 2/τ = 0.318309…
pub const FRAC_2_TAU: $Fixed<Frac> = shift!(FRAC_2_TAU, $Fixed<Frac>);
/// log<sub>10</sub> 2 = 0.301029…
pub const LOG10_2: U0F128 = split!(consts::LOG10_2 >> (128 - Frac::U32));
/// π/8 = 0.392699…
pub const FRAC_PI_8: $Fixed<Frac> = shift!(FRAC_PI_8, $Fixed<Frac>);
/// log<sub>10</sub> e = 0.434294…
pub const LOG10_E: U0F128 = split!(consts::LOG10_E >> (128 - Frac::U32));
/// 1/π = 0.318309…
pub const FRAC_1_PI: $Fixed<Frac> = shift!(FRAC_1_PI, $Fixed<Frac>);
/// log<sub>10</sub> 2 = 0.301029…
pub const LOG10_2: $Fixed<Frac> = shift!(LOG10_2, $Fixed<Frac>);
/// log<sub>10</sub> e = 0.434294…
pub const LOG10_E: $Fixed<Frac> = shift!(LOG10_E, $Fixed<Frac>);
}
}
// 0.5 ≤ constant < 1
impl<Frac: $LeEqU_C0> $Fixed<Frac> {
/// τ/8 = 0.785398…
pub const FRAC_TAU_8: U0F128 = split!(consts::FRAC_TAU_8 >> (128 - Frac::U32));
comment! {
"This block contains constants in the range 0.5 ≤ <i>x</i> < 1.
/// τ/12 = 0.523598…
pub const FRAC_TAU_12: U0F128 = split!(consts::FRAC_TAU_12 >> (128 - Frac::U32));
",
if_signed_else_empty_str!(
$Signedness,
"These constants are not representable in signed
fixed-point numbers with less than 1 integer bit.
/// 4/τ = 0.636619…
pub const FRAC_4_TAU: U0F128 = split!(consts::FRAC_4_TAU >> (128 - Frac::U32));
"
),
"# Examples
/// π/4 = 0.785398…
pub const FRAC_PI_4: U0F128 = split!(consts::FRAC_PI_4 >> (128 - Frac::U32));
```rust
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
">;
assert_eq!(Fix::LN_2, Fix::from_num(consts::LN_2));
assert!(0.5 <= Fix::LN_2 && Fix::LN_2 < 1);
```
",
if_signed_else_empty_str!(
$Signedness,
"
The following example fails to compile, since the maximum
representable value with ", $s_nbits, " fractional bits and 0 integer
bits is < 0.5.
/// π/6 = 0.523598…
pub const FRAC_PI_6: U0F128 = split!(consts::FRAC_PI_6 >> (128 - Frac::U32));
```compile_fail
use fixed::{consts, types::extra::U", $s_nbits, ", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U", $s_nbits, ">;
let _ = Fix::LN_2;
```
"
);
impl<Frac: Unsigned> $Fixed<Frac>
where
Frac: IsLessOrEqual<$LeEqU_C0, Output = True>,
{
/// τ/8 = 0.785398…
pub const FRAC_TAU_8: $Fixed<Frac> = shift!(FRAC_TAU_8, $Fixed<Frac>);
/// 2/π = 0.636619…
pub const FRAC_2_PI: U0F128 = split!(consts::FRAC_2_PI >> (128 - Frac::U32));
/// τ/12 = 0.523598
pub const FRAC_TAU_12: $Fixed<Frac> = shift!(FRAC_TAU_12, $Fixed<Frac>);
/// 1/√2 = 0.707106…
pub const FRAC_1_SQRT_2: U0F128 = split!(consts::FRAC_1_SQRT_2 >> (128 - Frac::U32));
/// 4/τ = 0.636619
pub const FRAC_4_TAU: $Fixed<Frac> = shift!(FRAC_4_TAU, $Fixed<Frac>);
/// ln 2 = 0.693147…
pub const LN_2: U0F128 = split!(consts::LN_2 >> (128 - Frac::U32));
/// π/4 = 0.785398…
pub const FRAC_PI_4: $Fixed<Frac> = shift!(FRAC_PI_4, $Fixed<Frac>);
/// π/6 = 0.523598…
pub const FRAC_PI_6: $Fixed<Frac> = shift!(FRAC_PI_6, $Fixed<Frac>);
/// 2/π = 0.636619…
pub const FRAC_2_PI: $Fixed<Frac> = shift!(FRAC_2_PI, $Fixed<Frac>);
/// 1/√2 = 0.707106…
pub const FRAC_1_SQRT_2: $Fixed<Frac> = shift!(FRAC_1_SQRT_2, $Fixed<Frac>);
/// ln 2 = 0.693147…
pub const LN_2: $Fixed<Frac> = shift!(LN_2, $Fixed<Frac>);
}
}
// 1 ≤ constant < 2
impl<Frac: $LeEqU_C1> $Fixed<Frac> {
/// τ/4 = 1.57079…
pub const FRAC_TAU_4: U1F127 = consts::FRAC_TAU_4 >> (127 - Frac::U32);
comment! {
"This block contains constants in the range 1  <i>x</i> < 2.
/// τ/6 = 1.04719…
pub const FRAC_TAU_6: U1F127 = consts::FRAC_TAU_6 >> (127 - Frac::U32);
These constants are not representable in ",
if_signed_unsigned!($Signedness, "signed", "unsigned"),
" fixed-point numbers with less than ",
if_signed_unsigned!($Signedness, "2 integer bits", "1 integer bit"),
".
/// π/2 = 1.57079…
pub const FRAC_PI_2: U1F127 = consts::FRAC_PI_2 >> (127 - Frac::U32);
# Examples
/// π/3 = 1.04719…
pub const FRAC_PI_3: U1F127 = consts::FRAC_PI_3 >> (127 - Frac::U32);
```rust
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m2, $s_nbits_m1),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m2, $s_nbits_m1),
">;
assert_eq!(Fix::LOG2_E, Fix::from_num(consts::LOG2_E));
assert!(1 <= Fix::LOG2_E && Fix::LOG2_E < 2);
```
/// 2/√π = 1.12837…
pub const FRAC_2_SQRT_PI: U1F127 = consts::FRAC_2_SQRT_PI >> (127 - Frac::U32);
The following example fails to compile, since the maximum
representable value with ",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
" fractional bits and ",
if_signed_unsigned!($Signedness, "1 integer bit", "0 integer bits"),
" is < 1.
/// √2 = 1.41421…
pub const SQRT_2: U1F127 = consts::SQRT_2 >> (127 - Frac::U32);
```compile_fail
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
">;
let _ = Fix::LOG2_E;
```
";
impl<Frac: Unsigned> $Fixed<Frac>
where
Frac: IsLessOrEqual<$LeEqU_C1, Output = True>,
{
/// τ/4 = 1.57079…
pub const FRAC_TAU_4: $Fixed<Frac> = shift!(FRAC_TAU_4, 127, $Fixed<Frac>);
/// log<sub>2</sub> e = 1.44269…
pub const LOG2_E: U1F127 = consts::LOG2_E >> (127 - Frac::U32);
/// τ/6 = 1.04719…
pub const FRAC_TAU_6: $Fixed<Frac> = shift!(FRAC_TAU_6, 127, $Fixed<Frac>);
/// π/2 = 1.57079…
pub const FRAC_PI_2: $Fixed<Frac> = shift!(FRAC_PI_2, 127, $Fixed<Frac>);
/// π/3 = 1.04719…
pub const FRAC_PI_3: $Fixed<Frac> = shift!(FRAC_PI_3, 127, $Fixed<Frac>);
/// 2/√π = 1.12837…
pub const FRAC_2_SQRT_PI: $Fixed<Frac> = shift!(FRAC_2_SQRT_PI, 127, $Fixed<Frac>);
/// √2 = 1.41421…
pub const SQRT_2: $Fixed<Frac> = shift!(SQRT_2, 127, $Fixed<Frac>);
/// log<sub>2</sub> e = 1.44269…
pub const LOG2_E: $Fixed<Frac> = shift!(LOG2_E, 127, $Fixed<Frac>);
}
}
// 2 ≤ constant < 4
impl<Frac: $LeEqU_C2> $Fixed<Frac> {
/// τ/2 = 3.14159…
pub const FRAC_TAU_2: U2F126 = consts::FRAC_TAU_2 >> (126 - Frac::U32);
comment! {
"This block contains constants in the range 2  <i>x</i> < 4.
/// τ/3 = 2.09439…
pub const FRAC_TAU_3: U2F126 = consts::FRAC_TAU_3 >> (126 - Frac::U32);
These constants are not representable in ",
if_signed_unsigned!($Signedness, "signed", "unsigned"),
" fixed-point numbers with less than ",
if_signed_unsigned!($Signedness, "3", "2"),
" integer bits.
/// π = 3.14159…
pub const PI: U2F126 = consts::PI >> (126 - Frac::U32);
# Examples
/// e = 2.71828…
pub const E: U2F126 = consts::E >> (126 - Frac::U32);
```rust
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m3, $s_nbits_m2),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m3, $s_nbits_m2),
">;
assert_eq!(Fix::E, Fix::from_num(consts::E));
assert!(2 <= Fix::E && Fix::E < 4);
```
/// log<sub>2</sub> 10 = 3.32192…
pub const LOG2_10: U2F126 = consts::LOG2_10 >> (126 - Frac::U32);
The following example fails to compile, since the maximum
representable value with ",
if_signed_unsigned!($Signedness, $s_nbits_m2, $s_nbits_m1),
" fractional bits and ",
if_signed_unsigned!($Signedness, "2 integer bits", "1 integer bit"),
" is < 2.
/// ln 10 = 2.30258…
pub const LN_10: U2F126 = consts::LN_10 >> (126 - Frac::U32);
```compile_fail
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m2, $s_nbits_m1),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m2, $s_nbits_m1),
">;
let _ = Fix::E;
```
";
impl<Frac: Unsigned> $Fixed<Frac>
where
Frac: IsLessOrEqual<$LeEqU_C2, Output = True>,
{
/// τ/2 = 3.14159…
pub const FRAC_TAU_2: $Fixed<Frac> = shift!(FRAC_TAU_2, 126, $Fixed<Frac>);
/// τ/3 = 2.09439…
pub const FRAC_TAU_3: $Fixed<Frac> = shift!(FRAC_TAU_3, 126, $Fixed<Frac>);
/// π = 3.14159…
pub const PI: $Fixed<Frac> = shift!(PI, 126, $Fixed<Frac>);
/// e = 2.71828…
pub const E: $Fixed<Frac> = shift!(E, 126, $Fixed<Frac>);
/// log<sub>2</sub> 10 = 3.32192…
pub const LOG2_10: $Fixed<Frac> = shift!(LOG2_10, 126, $Fixed<Frac>);
/// ln 10 = 2.30258…
pub const LN_10: $Fixed<Frac> = shift!(LN_10, 126, $Fixed<Frac>);
}
}
// 4 ≤ constant < 8
impl<Frac: $LeEqU_C3> $Fixed<Frac> {
/// τ = 6.28318…
pub const TAU: U3F125 = consts::TAU >> (125 - Frac::U32);
comment! {
"This block contains constants in the range 4  <i>x</i> < 8.
These constants are not representable in ",
if_signed_unsigned!($Signedness, "signed", "unsigned"),
" fixed-point numbers with less than ",
if_signed_unsigned!($Signedness, "4", "3"),
" integer bits.
# Examples
```rust
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m4, $s_nbits_m3),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m4, $s_nbits_m3),
">;
assert_eq!(Fix::TAU, Fix::from_num(consts::TAU));
assert!(4 <= Fix::TAU && Fix::TAU < 8);
```
The following example fails to compile, since the maximum
representable value with ",
if_signed_unsigned!($Signedness, $s_nbits_m3, $s_nbits_m2),
" fractional bits and ",
if_signed_unsigned!($Signedness, "3", "2"),
" integer bits is < 4.
```compile_fail
use fixed::{consts, types::extra::U",
if_signed_unsigned!($Signedness, $s_nbits_m3, $s_nbits_m2),
", ", $s_fixed, "};
type Fix = ", $s_fixed, "<U",
if_signed_unsigned!($Signedness, $s_nbits_m3, $s_nbits_m2),
">;
let _ = Fix::TAU;
```
";
impl<Frac: Unsigned> $Fixed<Frac>
where
Frac: IsLessOrEqual<$LeEqU_C3, Output = True>,
{
/// τ = 6.28318…
pub const TAU: $Fixed<Frac> = shift!(TAU, 125, $Fixed<Frac>);
}
}
};
}