macro_rules! shift {
($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, $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
) => {
comment! {
"This block contains constants in the range 0 ≤ <i>x</i> < 0.5.
# Examples
```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> {
pub const FRAC_1_TAU: $Fixed<Frac> = shift!(FRAC_1_TAU, $Fixed<Frac>);
pub const FRAC_2_TAU: $Fixed<Frac> = shift!(FRAC_2_TAU, $Fixed<Frac>);
pub const FRAC_PI_8: $Fixed<Frac> = shift!(FRAC_PI_8, $Fixed<Frac>);
pub const FRAC_1_PI: $Fixed<Frac> = shift!(FRAC_1_PI, $Fixed<Frac>);
pub const LOG10_2: $Fixed<Frac> = shift!(LOG10_2, $Fixed<Frac>);
pub const LOG10_E: $Fixed<Frac> = shift!(LOG10_E, $Fixed<Frac>);
}
}
comment! {
"This block contains constants in the range 0.5 ≤ <i>x</i> < 1.
",
if_signed_else_empty_str!(
$Signedness,
"These constants are not representable in signed
fixed-point numbers with less than 1 integer bit.
"
),
"# Examples
```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.
```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>,
{
pub const FRAC_TAU_8: $Fixed<Frac> = shift!(FRAC_TAU_8, $Fixed<Frac>);
pub const FRAC_TAU_12: $Fixed<Frac> = shift!(FRAC_TAU_12, $Fixed<Frac>);
pub const FRAC_4_TAU: $Fixed<Frac> = shift!(FRAC_4_TAU, $Fixed<Frac>);
pub const FRAC_PI_4: $Fixed<Frac> = shift!(FRAC_PI_4, $Fixed<Frac>);
pub const FRAC_PI_6: $Fixed<Frac> = shift!(FRAC_PI_6, $Fixed<Frac>);
pub const FRAC_2_PI: $Fixed<Frac> = shift!(FRAC_2_PI, $Fixed<Frac>);
pub const FRAC_1_SQRT_2: $Fixed<Frac> = shift!(FRAC_1_SQRT_2, $Fixed<Frac>);
pub const LN_2: $Fixed<Frac> = shift!(LN_2, $Fixed<Frac>);
pub const FRAC_1_PHI: $Fixed<Frac> = shift!(FRAC_1_PHI, $Fixed<Frac>);
}
}
comment! {
"This block contains constants in the range 1 ≤ <i>x</i> < 2.
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"),
".
# Examples
```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);
```
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.
```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>,
{
pub const FRAC_TAU_4: $Fixed<Frac> = shift!(FRAC_TAU_4, 127, $Fixed<Frac>);
pub const FRAC_TAU_6: $Fixed<Frac> = shift!(FRAC_TAU_6, 127, $Fixed<Frac>);
pub const FRAC_PI_2: $Fixed<Frac> = shift!(FRAC_PI_2, 127, $Fixed<Frac>);
pub const FRAC_PI_3: $Fixed<Frac> = shift!(FRAC_PI_3, 127, $Fixed<Frac>);
pub const FRAC_2_SQRT_PI: $Fixed<Frac> = shift!(FRAC_2_SQRT_PI, 127, $Fixed<Frac>);
pub const SQRT_2: $Fixed<Frac> = shift!(SQRT_2, 127, $Fixed<Frac>);
pub const LOG2_E: $Fixed<Frac> = shift!(LOG2_E, 127, $Fixed<Frac>);
pub const PHI: $Fixed<Frac> = shift!(PHI, 127, $Fixed<Frac>);
}
}
comment! {
"This block contains constants in the range 2 ≤ <i>x</i> < 4.
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.
# Examples
```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);
```
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.
```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>,
{
pub const FRAC_TAU_2: $Fixed<Frac> = shift!(FRAC_TAU_2, 126, $Fixed<Frac>);
pub const FRAC_TAU_3: $Fixed<Frac> = shift!(FRAC_TAU_3, 126, $Fixed<Frac>);
pub const PI: $Fixed<Frac> = shift!(PI, 126, $Fixed<Frac>);
pub const E: $Fixed<Frac> = shift!(E, 126, $Fixed<Frac>);
pub const LOG2_10: $Fixed<Frac> = shift!(LOG2_10, 126, $Fixed<Frac>);
pub const LN_10: $Fixed<Frac> = shift!(LN_10, 126, $Fixed<Frac>);
}
}
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>,
{
pub const TAU: $Fixed<Frac> = shift!(TAU, 125, $Fixed<Frac>);
}
}
};
}