From 59b407ba612a148c0b86def1cecb82477473c651 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Sat, 26 Jan 2019 21:44:34 +0100 Subject: [PATCH] add bool to fixed conversion --- README.md | 4 ++-- RELEASES.md | 2 +- src/convert.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 2 +- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0f64a1e..0c449c4 100644 --- a/README.md +++ b/README.md @@ -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. ## What’s 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) diff --git a/RELEASES.md b/RELEASES.md index e464ab7..39e8f28 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -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) ========================== diff --git a/src/convert.rs b/src/convert.rs index 7e38bf1..3a2dc2b 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -14,7 +14,7 @@ // . 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 From for $DstU + where + FracDst: Unsigned + + IsLessOrEqual<$DstBits, Output = True> + + IsLessOrEqual<<$DstBits as Sub>::Output, Output = True>, + { + #[inline] + fn from(src: bool) -> $DstU { + let unshifted = $DstU::::from_bits(src.into()).to_bits(); + let shift = FracDst::to_u32(); + $DstU::::from_bits(unshifted << shift) + } + } + + // Condition: FracDst <= $DstBits - 2 + impl From for $DstI + where + FracDst: Unsigned + + IsLessOrEqual<$DstBits, Output = True> + + IsLessOrEqual<<$DstBits as Sub>::Output, Output = True>, + { + #[inline] + fn from(src: bool) -> $DstI { + let unshifted = $DstI::::from_bits(src.into()).to_bits(); + let shift = FracDst::to_u32(); + $DstI::::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> for $DstU { @@ -388,6 +428,14 @@ mod tests { } } + #[test] + fn from_bool() { + assert_eq!(FixedI8::::from(true), 1); + assert_eq!(FixedI8::::from(false), 0); + assert_eq!(FixedI128::::from(true), 1); + assert_eq!(FixedU128::::from(true), 1); + } + #[test] fn signed_from_f32() { type Fix = FixedI8; diff --git a/src/lib.rs b/src/lib.rs index 20cf740..1058a12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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