add bool to fixed conversion

This commit is contained in:
Trevor Spiteri 2019-01-26 21:44:34 +01:00
parent ef902eb60e
commit 59b407ba61
4 changed files with 53 additions and 5 deletions

View File

@ -34,7 +34,7 @@ fixed-point numbers, and in the range 0 ≤ *x* < 1 for unsigned
fixed-point numbers.
All lossless infallible conversions between fixed-point numbers and
integer primitives are implemented. That is, you can use [`From`] or
numeric primitives are implemented. That is, you can use [`From`] or
[`Into`] for the conversions that always work without losing any bits.
## Whats new
@ -42,7 +42,7 @@ integer primitives are implemented. That is, you can use [`From`] or
### Version 0.1.5 (unreleased)
* Lossless infallible conversions between fixed-point numbers and
integer primitives are now supported using [`From`] and [`Into`].
numeric primitives are now supported using [`From`] and [`Into`].
### Version 0.1.4 news (2018-11-29)

View File

@ -9,7 +9,7 @@ Version 0.1.5 (unreleased)
==========================
* Lossless infallible conversions between fixed-point numbers and
integer primitives are now supported using `From` and `Into`.
numeric primitives are now supported using `From` and `Into`.
Version 0.1.4 (2018-11-29)
==========================

View File

@ -14,7 +14,7 @@
// <https://opensource.org/licenses/MIT>.
use core::ops::{Add, Sub};
use frac::{IsGreaterOrEqual, IsLessOrEqual, True, Unsigned, U0, U1, U128, U16, U32, U64, U8};
use frac::{IsGreaterOrEqual, IsLessOrEqual, True, Unsigned, U0, U1, U128, U16, U2, U32, U64, U8};
use {
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
FixedU8,
@ -189,6 +189,46 @@ prim_to_fixed! { (u64, i64, U64) -> (FixedU128, FixedI128, U128) }
prim_to_fixed! { (u128, i128) -> (FixedU128, FixedI128) }
macro_rules! bool_to_fixed {
($DstU:ident, $DstI:ident, $DstBits:ident) => {
// Condition: FracDst <= $DstBits - 1
impl<FracDst> From<bool> for $DstU<FracDst>
where
FracDst: Unsigned
+ IsLessOrEqual<$DstBits, Output = True>
+ IsLessOrEqual<<$DstBits as Sub<U1>>::Output, Output = True>,
{
#[inline]
fn from(src: bool) -> $DstU<FracDst> {
let unshifted = $DstU::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
$DstU::<FracDst>::from_bits(unshifted << shift)
}
}
// Condition: FracDst <= $DstBits - 2
impl<FracDst> From<bool> for $DstI<FracDst>
where
FracDst: Unsigned
+ IsLessOrEqual<$DstBits, Output = True>
+ IsLessOrEqual<<$DstBits as Sub<U2>>::Output, Output = True>,
{
#[inline]
fn from(src: bool) -> $DstI<FracDst> {
let unshifted = $DstI::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
$DstI::<FracDst>::from_bits(unshifted << shift)
}
}
};
}
bool_to_fixed! { FixedU8, FixedI8, U8 }
bool_to_fixed! { FixedU16, FixedI16, U16 }
bool_to_fixed! { FixedU32, FixedI32, U32 }
bool_to_fixed! { FixedU64, FixedI64, U64 }
bool_to_fixed! { FixedU128, FixedI128, U128 }
macro_rules! fixed_to_prim {
(($SrcU:ident, $SrcI:ident) -> ($DstU:ident, $DstI:ident)) => {
impl From<$SrcU<U0>> for $DstU {
@ -388,6 +428,14 @@ mod tests {
}
}
#[test]
fn from_bool() {
assert_eq!(FixedI8::<frac::U6>::from(true), 1);
assert_eq!(FixedI8::<frac::U6>::from(false), 0);
assert_eq!(FixedI128::<frac::U64>::from(true), 1);
assert_eq!(FixedU128::<frac::U127>::from(true), 1);
}
#[test]
fn signed_from_f32() {
type Fix = FixedI8<frac::U4>;

View File

@ -43,7 +43,7 @@ fixed-point numbers, and in the range 0 ≤ *x* < 1 for unsigned
fixed-point numbers.
All lossless infallible conversions between fixed-point numbers and
integer primitives are implemented. That is, you can use [`From`] or
numeric primitives are implemented. That is, you can use [`From`] or
[`Into`] for the conversions that always work without losing any bits.
## Quick example