fix comparison of e.g. I0F16 with +0.5
This commit is contained in:
parent
4c25f002a1
commit
5db3b17284
|
@ -76,6 +76,9 @@ The conversions supported cover the following cases.
|
|||
|
||||
### Version 0.5.5 news (unreleased)
|
||||
|
||||
* Bug fix: comparison between a signed fixed-point number of type
|
||||
`FixedI` and a number that would overflow when converting to
|
||||
`FixedI` by exactly one bit was giving an incorrect result.
|
||||
* The following associated constants were added to all fixed-point
|
||||
types, to the [`Fixed`] trait, and to the [`Wrapping`] wrapper:
|
||||
* [`MIN`], [`MAX`]
|
||||
|
|
|
@ -8,6 +8,9 @@ as-is, without any warranty. -->
|
|||
Version 0.5.5 (unreleased)
|
||||
==========================
|
||||
|
||||
* Bug fix: comparison between a signed fixed-point number of type
|
||||
`FixedI` and a number that would overflow when converting to
|
||||
`FixedI` by exactly one bit was giving an incorrect result.
|
||||
* The following associated constants were added to all fixed-point
|
||||
types, to the `Fixed` trait, and to the `Wrapping` wrapper:
|
||||
* `MIN`, `MAX`
|
||||
|
|
137
src/cmp.rs
137
src/cmp.rs
|
@ -34,18 +34,22 @@ macro_rules! fixed_cmp_fixed {
|
|||
Self::FRAC_NBITS,
|
||||
Self::INT_NBITS,
|
||||
);
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
let (rhs_is_neg, rhs_bits) = match conv.bits {
|
||||
Widest::Unsigned(bits) => (false, bits as <Self as Fixed>::Bits),
|
||||
Widest::Negative(bits) => (true, bits as <Self as Fixed>::Bits),
|
||||
};
|
||||
conv.dir == Ordering::Equal && !conv.overflow && rhs_bits == self.to_bits()
|
||||
conv.dir == Ordering::Equal
|
||||
&& !conv.overflow
|
||||
&& rhs_is_neg == rhs_bits.is_negative()
|
||||
&& rhs_bits == self.to_bits()
|
||||
}
|
||||
}
|
||||
|
||||
impl<FracLhs: $LhsLeEqU, FracRhs: $RhsLeEqU> PartialOrd<$Rhs<FracRhs>> for $Lhs<FracLhs> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, rhs: &$Rhs<FracRhs>) -> Option<Ordering> {
|
||||
match (self.to_bits().is_negative(), rhs.to_bits().is_negative()) {
|
||||
let rhs_is_neg = rhs.to_bits().is_negative();
|
||||
match (self.to_bits().is_negative(), rhs_is_neg) {
|
||||
(false, true) => return Some(Ordering::Greater),
|
||||
(true, false) => return Some(Ordering::Less),
|
||||
_ => {}
|
||||
|
@ -55,23 +59,24 @@ macro_rules! fixed_cmp_fixed {
|
|||
Self::FRAC_NBITS,
|
||||
Self::INT_NBITS,
|
||||
);
|
||||
if conv.overflow {
|
||||
return if rhs.to_bits().is_negative() {
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
};
|
||||
if conv.overflow || rhs_bits.is_negative() != rhs_is_neg {
|
||||
return if rhs_is_neg {
|
||||
Some(Ordering::Greater)
|
||||
} else {
|
||||
Some(Ordering::Less)
|
||||
};
|
||||
}
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
};
|
||||
Some(self.to_bits().cmp(&rhs_bits).then(conv.dir))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lt(&self, rhs: &$Rhs<FracRhs>) -> bool {
|
||||
match (self.to_bits().is_negative(), rhs.to_bits().is_negative()) {
|
||||
let rhs_is_neg = rhs.to_bits().is_negative();
|
||||
match (self.to_bits().is_negative(), rhs_is_neg) {
|
||||
(false, true) => return false,
|
||||
(true, false) => return true,
|
||||
_ => {}
|
||||
|
@ -81,15 +86,15 @@ macro_rules! fixed_cmp_fixed {
|
|||
Self::FRAC_NBITS,
|
||||
Self::INT_NBITS,
|
||||
);
|
||||
if conv.overflow {
|
||||
return !rhs.to_bits().is_negative();
|
||||
}
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
};
|
||||
self.to_bits() < rhs_bits
|
||||
|| (self.to_bits() == rhs_bits && conv.dir == Ordering::Less)
|
||||
if conv.overflow || rhs_bits.is_negative() != rhs_is_neg {
|
||||
return !rhs_is_neg;
|
||||
}
|
||||
let lhs_bits = self.to_bits();
|
||||
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && conv.dir == Ordering::Less)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -191,11 +196,14 @@ macro_rules! fixed_cmp_float {
|
|||
FloatKind::Finite { conv, .. } => conv,
|
||||
_ => return false,
|
||||
};
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
let (rhs_is_neg, rhs_bits) = match conv.bits {
|
||||
Widest::Unsigned(bits) => (false, bits as <Self as Fixed>::Bits),
|
||||
Widest::Negative(bits) => (true, bits as <Self as Fixed>::Bits),
|
||||
};
|
||||
conv.dir == Ordering::Equal && !conv.overflow && rhs_bits == self.to_bits()
|
||||
conv.dir == Ordering::Equal
|
||||
&& !conv.overflow
|
||||
&& rhs_is_neg == rhs_bits.is_negative()
|
||||
&& rhs_bits == self.to_bits()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,17 +234,17 @@ macro_rules! fixed_cmp_float {
|
|||
(true, false) => return Some(Ordering::Less),
|
||||
_ => {}
|
||||
}
|
||||
if conv.overflow {
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
};
|
||||
if conv.overflow || rhs_bits.is_negative() != rhs_is_neg {
|
||||
return if rhs_is_neg {
|
||||
Some(Ordering::Greater)
|
||||
} else {
|
||||
Some(Ordering::Less)
|
||||
};
|
||||
}
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
};
|
||||
Some(self.to_bits().cmp(&rhs_bits).then(conv.dir))
|
||||
}
|
||||
|
||||
|
@ -254,13 +262,13 @@ macro_rules! fixed_cmp_float {
|
|||
(true, false) => return true,
|
||||
_ => {}
|
||||
}
|
||||
if conv.overflow {
|
||||
return !rhs_is_neg;
|
||||
}
|
||||
let rhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||
};
|
||||
if conv.overflow || rhs_bits.is_negative() != rhs_is_neg {
|
||||
return !rhs_is_neg;
|
||||
}
|
||||
let lhs_bits = self.to_bits();
|
||||
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && conv.dir == Ordering::Less)
|
||||
}
|
||||
|
@ -301,13 +309,13 @@ macro_rules! fixed_cmp_float {
|
|||
(true, false) => return true,
|
||||
_ => {}
|
||||
}
|
||||
if conv.overflow {
|
||||
return lhs_is_neg;
|
||||
}
|
||||
let lhs_bits = match conv.bits {
|
||||
Widest::Unsigned(bits) => bits as <$Fix<Frac> as Fixed>::Bits,
|
||||
Widest::Negative(bits) => bits as <$Fix<Frac> as Fixed>::Bits,
|
||||
};
|
||||
if conv.overflow || lhs_bits.is_negative() != lhs_is_neg {
|
||||
return lhs_is_neg;
|
||||
}
|
||||
let rhs_bits = rhs.to_bits();
|
||||
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && conv.dir == Ordering::Greater)
|
||||
}
|
||||
|
@ -509,4 +517,69 @@ mod tests {
|
|||
assert_eq!(a, 1i32 << 12);
|
||||
assert_eq!(b, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_i0_with_half() {
|
||||
use crate::types::*;
|
||||
assert_eq!(I0F32::checked_from_num(0.5), None);
|
||||
for &float in &[-0.5, -0.25, 0., 0.25, 0.49] {
|
||||
let fixed = I0F32::from_num(float);
|
||||
let half = U0F32::from_num(0.5);
|
||||
assert_eq!(fixed < half, float < 0.5, "{} < {}", fixed, half);
|
||||
assert_eq!(fixed == half, float == 0.5, "{} == {}", fixed, half);
|
||||
assert_eq!(fixed > half, float > 0.5, "{} > {}", fixed, half);
|
||||
assert_eq!(
|
||||
fixed.partial_cmp(&half),
|
||||
float.partial_cmp(&0.5),
|
||||
"{}.partial_cmp(&{})",
|
||||
fixed,
|
||||
half
|
||||
);
|
||||
assert_eq!(half < fixed, fixed > half);
|
||||
assert_eq!(half == fixed, fixed == half);
|
||||
assert_eq!(half > fixed, fixed < half);
|
||||
assert_eq!(
|
||||
half.partial_cmp(&fixed),
|
||||
fixed.partial_cmp(&half).map(Ordering::reverse)
|
||||
);
|
||||
|
||||
let half = I1F31::from_num(0.5);
|
||||
assert_eq!(fixed < half, float < 0.5, "{} < {}", fixed, half);
|
||||
assert_eq!(fixed == half, float == 0.5, "{} == {}", fixed, half);
|
||||
assert_eq!(fixed > half, float > 0.5, "{} > {}", fixed, half);
|
||||
assert_eq!(
|
||||
fixed.partial_cmp(&half),
|
||||
float.partial_cmp(&0.5),
|
||||
"{}.partial_cmp(&{})",
|
||||
fixed,
|
||||
half
|
||||
);
|
||||
assert_eq!(half < fixed, fixed > half);
|
||||
assert_eq!(half == fixed, fixed == half);
|
||||
assert_eq!(half > fixed, fixed < half);
|
||||
assert_eq!(
|
||||
half.partial_cmp(&fixed),
|
||||
fixed.partial_cmp(&half).map(Ordering::reverse)
|
||||
);
|
||||
|
||||
let half = 0.5f32;
|
||||
assert_eq!(fixed < half, float < 0.5, "{} < {}", fixed, half);
|
||||
assert_eq!(fixed == half, float == 0.5, "{} == {}", fixed, half);
|
||||
assert_eq!(fixed > half, float > 0.5, "{} > {}", fixed, half);
|
||||
assert_eq!(
|
||||
fixed.partial_cmp(&half),
|
||||
float.partial_cmp(&0.5),
|
||||
"{}.partial_cmp(&{})",
|
||||
fixed,
|
||||
half
|
||||
);
|
||||
assert_eq!(half < fixed, fixed > half);
|
||||
assert_eq!(half == fixed, fixed == half);
|
||||
assert_eq!(half > fixed, fixed < half);
|
||||
assert_eq!(
|
||||
half.partial_cmp(&fixed),
|
||||
fixed.partial_cmp(&half).map(Ordering::reverse)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
41
src/lib.rs
41
src/lib.rs
|
@ -311,13 +311,16 @@ mod macros_round;
|
|||
mod macros_no_frac;
|
||||
#[macro_use]
|
||||
mod macros_frac;
|
||||
#[macro_use]
|
||||
mod macros_const;
|
||||
|
||||
macro_rules! fixed {
|
||||
(
|
||||
$description:expr,
|
||||
$Fixed:ident($Inner:ty, $LeEqU:tt, $s_nbits:expr, $s_nbits_m4:expr),
|
||||
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
|
||||
$UInner:ty, $Signedness:tt
|
||||
$UInner:ty, $Signedness:tt,
|
||||
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt
|
||||
) => {
|
||||
fixed! {
|
||||
$description,
|
||||
|
@ -332,7 +335,8 @@ macro_rules! fixed {
|
|||
$Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr, $s_nbits_m4:expr
|
||||
),
|
||||
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
|
||||
$UInner:ty, $Signedness:tt
|
||||
$UInner:ty, $Signedness:tt,
|
||||
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt
|
||||
) => {
|
||||
comment! {
|
||||
$description,
|
||||
|
@ -409,6 +413,9 @@ assert_eq!(two_point_75.to_string(), \"2.8\");
|
|||
$Fixed[$s_fixed]($Inner[$s_inner], $LeEqU, $s_nbits, $s_nbits_m4),
|
||||
$UInner, $Signedness
|
||||
}
|
||||
fixed_const! {
|
||||
$Fixed[$s_fixed]($LeEqU, $LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -416,19 +423,22 @@ fixed! {
|
|||
"An eight-bit fixed-point unsigned",
|
||||
FixedU8(u8, LeEqU8, "8", "4"),
|
||||
1, "0x12", "[0x12]", "[0x12]",
|
||||
u8, Unsigned
|
||||
u8, Unsigned,
|
||||
LeEqU8, LeEqU7, LeEqU6, LeEqU5
|
||||
}
|
||||
fixed! {
|
||||
"A 16-bit fixed-point unsigned",
|
||||
FixedU16(u16, LeEqU16, "16", "12"),
|
||||
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
|
||||
u16, Unsigned
|
||||
u16, Unsigned,
|
||||
LeEqU16, LeEqU15, LeEqU14, LeEqU13
|
||||
}
|
||||
fixed! {
|
||||
"A 32-bit fixed-point unsigned",
|
||||
FixedU32(u32, LeEqU32, "32", "28"),
|
||||
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
|
||||
u32, Unsigned
|
||||
u32, Unsigned,
|
||||
LeEqU32, LeEqU31, LeEqU30, LeEqU29
|
||||
}
|
||||
fixed! {
|
||||
"A 64-bit fixed-point unsigned",
|
||||
|
@ -436,7 +446,8 @@ fixed! {
|
|||
8, "0x1234_5678_9ABC_DEF0",
|
||||
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
|
||||
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
|
||||
u64, Unsigned
|
||||
u64, Unsigned,
|
||||
LeEqU64, LeEqU63, LeEqU62, LeEqU61
|
||||
}
|
||||
fixed! {
|
||||
"A 128-bit fixed-point unsigned",
|
||||
|
@ -446,25 +457,29 @@ fixed! {
|
|||
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
|
||||
u128, Unsigned,
|
||||
LeEqU128, LeEqU127, LeEqU126, LeEqU125
|
||||
}
|
||||
fixed! {
|
||||
"An eight-bit fixed-point signed",
|
||||
FixedI8(i8, LeEqU8, "8", "4"),
|
||||
1, "0x12", "[0x12]", "[0x12]",
|
||||
u8, Signed
|
||||
u8, Signed,
|
||||
LeEqU7, LeEqU6, LeEqU5, LeEqU4
|
||||
}
|
||||
fixed! {
|
||||
"A 16-bit fixed-point signed",
|
||||
FixedI16(i16, LeEqU16, "16", "12"),
|
||||
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
|
||||
u16, Signed
|
||||
u16, Signed,
|
||||
LeEqU15, LeEqU14, LeEqU13, LeEqU12
|
||||
}
|
||||
fixed! {
|
||||
"A 32-bit fixed-point signed",
|
||||
FixedI32(i32, LeEqU32, "32", "28"),
|
||||
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
|
||||
u32, Signed
|
||||
u32, Signed,
|
||||
LeEqU31, LeEqU30, LeEqU29, LeEqU28
|
||||
}
|
||||
fixed! {
|
||||
"A 64-bit fixed-point signed",
|
||||
|
@ -472,7 +487,8 @@ fixed! {
|
|||
8, "0x1234_5678_9ABC_DEF0",
|
||||
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
|
||||
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
|
||||
u64, Signed
|
||||
u64, Signed,
|
||||
LeEqU63, LeEqU62, LeEqU61, LeEqU60
|
||||
}
|
||||
fixed! {
|
||||
"A 128-bit fixed-point signed",
|
||||
|
@ -482,7 +498,8 @@ fixed! {
|
|||
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
|
||||
u128, Signed,
|
||||
LeEqU127, LeEqU126, LeEqU125, LeEqU124
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright © 2018–2020 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>.
|
||||
|
||||
// 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! fixed_const {
|
||||
(
|
||||
$Fixed:ident[$s_fixed:expr](
|
||||
$LeEqU:tt, $LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3: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));
|
||||
|
||||
/// 2/τ = 0.318309…
|
||||
pub const FRAC_2_TAU: U0F128 = split!(consts::FRAC_2_TAU >> (128 - Frac::U32));
|
||||
|
||||
/// π/8 = 0.392699…
|
||||
pub const FRAC_PI_8: U0F128 = split!(consts::FRAC_PI_8 >> (128 - Frac::U32));
|
||||
|
||||
/// 1/π = 0.318309…
|
||||
pub const FRAC_1_PI: U0F128 = split!(consts::FRAC_1_PI >> (128 - Frac::U32));
|
||||
|
||||
/// log<sub>10</sub> 2 = 0.301029…
|
||||
pub const LOG10_2: U0F128 = split!(consts::LOG10_2 >> (128 - Frac::U32));
|
||||
|
||||
/// log<sub>10</sub> e = 0.434294…
|
||||
pub const LOG10_E: U0F128 = split!(consts::LOG10_E >> (128 - Frac::U32));
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
/// τ/12 = 0.523598…
|
||||
pub const FRAC_TAU_12: U0F128 = split!(consts::FRAC_TAU_12 >> (128 - Frac::U32));
|
||||
|
||||
/// 4/τ = 0.636619…
|
||||
pub const FRAC_4_TAU: U0F128 = split!(consts::FRAC_4_TAU >> (128 - Frac::U32));
|
||||
|
||||
/// π/4 = 0.785398…
|
||||
pub const FRAC_PI_4: U0F128 = split!(consts::FRAC_PI_4 >> (128 - Frac::U32));
|
||||
|
||||
/// π/6 = 0.523598…
|
||||
pub const FRAC_PI_6: U0F128 = split!(consts::FRAC_PI_6 >> (128 - Frac::U32));
|
||||
|
||||
/// 2/π = 0.636619…
|
||||
pub const FRAC_2_PI: U0F128 = split!(consts::FRAC_2_PI >> (128 - Frac::U32));
|
||||
|
||||
/// 1/√2 = 0.707106…
|
||||
pub const FRAC_1_SQRT_2: U0F128 = split!(consts::FRAC_1_SQRT_2 >> (128 - Frac::U32));
|
||||
|
||||
/// ln 2 = 0.693147…
|
||||
pub const LN_2: U0F128 = split!(consts::LN_2 >> (128 - Frac::U32));
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
/// τ/6 = 1.04719…
|
||||
pub const FRAC_TAU_6: U1F127 = consts::FRAC_TAU_6 >> (127 - Frac::U32);
|
||||
|
||||
/// π/2 = 1.57079…
|
||||
pub const FRAC_PI_2: U1F127 = consts::FRAC_PI_2 >> (127 - Frac::U32);
|
||||
|
||||
/// π/3 = 1.04719…
|
||||
pub const FRAC_PI_3: U1F127 = consts::FRAC_PI_3 >> (127 - Frac::U32);
|
||||
|
||||
/// 2/√π = 1.12837…
|
||||
pub const FRAC_2_SQRT_PI: U1F127 = consts::FRAC_2_SQRT_PI >> (127 - Frac::U32);
|
||||
|
||||
/// √2 = 1.41421…
|
||||
pub const SQRT_2: U1F127 = consts::SQRT_2 >> (127 - Frac::U32);
|
||||
|
||||
/// log<sub>2</sub> e = 1.44269…
|
||||
pub const LOG2_E: U1F127 = consts::LOG2_E >> (127 - Frac::U32);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
/// τ/3 = 2.09439…
|
||||
pub const FRAC_TAU_3: U2F126 = consts::FRAC_TAU_3 >> (126 - Frac::U32);
|
||||
|
||||
/// π = 3.14159…
|
||||
pub const PI: U2F126 = consts::PI >> (126 - Frac::U32);
|
||||
|
||||
/// e = 2.71828…
|
||||
pub const E: U2F126 = consts::E >> (126 - Frac::U32);
|
||||
|
||||
/// log<sub>2</sub> 10 = 3.32192…
|
||||
pub const LOG2_10: U2F126 = consts::LOG2_10 >> (126 - Frac::U32);
|
||||
|
||||
/// ln 10 = 2.30258…
|
||||
pub const LN_10: U2F126 = consts::LN_10 >> (126 - Frac::U32);
|
||||
}
|
||||
|
||||
// 4 ≤ constant < 8
|
||||
impl<Frac: $LeEqU_C3> $Fixed<Frac> {
|
||||
/// τ = 6.28318…
|
||||
pub const TAU: U3F125 = consts::TAU >> (125 - Frac::U32);
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue