implement infallible fixed to primitive conversions
This commit is contained in:
parent
266f2910ce
commit
b71b41cd70
11
README.md
11
README.md
|
@ -33,8 +33,17 @@ fixed-point number lies in the range −0.5 ≤ *x* < 0.5 for signed
|
|||
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
|
||||
[`Into`] for the conversions that always work without losing any bits.
|
||||
|
||||
## What’s new
|
||||
|
||||
### Version 0.1.5 (unreleased)
|
||||
|
||||
* Lossless infallible conversions between fixed-point numbers and
|
||||
integer primitives are now supported using [`From`] and [`Into`].
|
||||
|
||||
### Version 0.1.4 news (2018-11-29)
|
||||
|
||||
* Division is now implemented for [`FixedI128`] and [`FixedU128`].
|
||||
|
@ -129,5 +138,7 @@ additional terms or conditions.
|
|||
[`FixedU32`]: https://docs.rs/fixed/0.1.4/fixed/struct.FixedU32.html
|
||||
[`FixedU64`]: https://docs.rs/fixed/0.1.4/fixed/struct.FixedU64.html
|
||||
[`FixedU8`]: https://docs.rs/fixed/0.1.4/fixed/struct.FixedU8.html
|
||||
[`From`]: https://doc.rust-lang.org/nightly/std/convert/trait.From.html
|
||||
[`Into`]: https://doc.rust-lang.org/nightly/std/convert/trait.Into.html
|
||||
[`f16`]: https://docs.rs/half/^1/half/struct.f16.html
|
||||
[const generics]: https://github.com/rust-lang/rust/issues/44580
|
||||
|
|
|
@ -5,6 +5,12 @@ modification, are permitted in any medium without royalty provided the
|
|||
copyright notice and this notice are preserved. This file is offered
|
||||
as-is, without any warranty. -->
|
||||
|
||||
Version 0.1.5 (unreleased)
|
||||
==========================
|
||||
|
||||
* Lossless infallible conversions between fixed-point numbers and
|
||||
integer primitives are now supported using `From` and `Into`.
|
||||
|
||||
Version 0.1.4 (2018-11-29)
|
||||
==========================
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ convert! { (FixedU32, FixedI32, U32) -> (FixedU128, FixedI128, U128) }
|
|||
|
||||
convert! { (FixedU64, FixedI64, U64) -> (FixedU128, FixedI128, U128) }
|
||||
|
||||
macro_rules! prim_convert {
|
||||
macro_rules! prim_to_fixed {
|
||||
(($SrcU:ident, $SrcI:ident, $SrcBits:ident) -> ($DstU:ident, $DstI:ident, $DstBits:ident)) => {
|
||||
// Condition: FracDst <= $DstBits - $SrcBits
|
||||
impl<FracDst> From<$SrcU> for $DstU<FracDst>
|
||||
|
@ -169,25 +169,85 @@ macro_rules! prim_convert {
|
|||
};
|
||||
}
|
||||
|
||||
prim_convert! { (u8, i8) -> (FixedU8, FixedI8) }
|
||||
prim_convert! { (u8, i8, U8) -> (FixedU16, FixedI16, U16) }
|
||||
prim_convert! { (u8, i8, U8) -> (FixedU32, FixedI32, U32) }
|
||||
prim_convert! { (u8, i8, U8) -> (FixedU64, FixedI64, U64) }
|
||||
prim_convert! { (u8, i8, U8) -> (FixedU128, FixedI128, U128) }
|
||||
prim_to_fixed! { (u8, i8) -> (FixedU8, FixedI8) }
|
||||
prim_to_fixed! { (u8, i8, U8) -> (FixedU16, FixedI16, U16) }
|
||||
prim_to_fixed! { (u8, i8, U8) -> (FixedU32, FixedI32, U32) }
|
||||
prim_to_fixed! { (u8, i8, U8) -> (FixedU64, FixedI64, U64) }
|
||||
prim_to_fixed! { (u8, i8, U8) -> (FixedU128, FixedI128, U128) }
|
||||
|
||||
prim_convert! { (u16, i16) -> (FixedU16, FixedI16) }
|
||||
prim_convert! { (u16, i16, U16) -> (FixedU32, FixedI32, U32) }
|
||||
prim_convert! { (u16, i16, U16) -> (FixedU64, FixedI64, U64) }
|
||||
prim_convert! { (u16, i16, U16) -> (FixedU128, FixedI128, U128) }
|
||||
prim_to_fixed! { (u16, i16) -> (FixedU16, FixedI16) }
|
||||
prim_to_fixed! { (u16, i16, U16) -> (FixedU32, FixedI32, U32) }
|
||||
prim_to_fixed! { (u16, i16, U16) -> (FixedU64, FixedI64, U64) }
|
||||
prim_to_fixed! { (u16, i16, U16) -> (FixedU128, FixedI128, U128) }
|
||||
|
||||
prim_convert! { (u32, i32) -> (FixedU32, FixedI32) }
|
||||
prim_convert! { (u32, i32, U32) -> (FixedU64, FixedI64, U64) }
|
||||
prim_convert! { (u32, i32, U32) -> (FixedU128, FixedI128, U128) }
|
||||
prim_to_fixed! { (u32, i32) -> (FixedU32, FixedI32) }
|
||||
prim_to_fixed! { (u32, i32, U32) -> (FixedU64, FixedI64, U64) }
|
||||
prim_to_fixed! { (u32, i32, U32) -> (FixedU128, FixedI128, U128) }
|
||||
|
||||
prim_convert! { (u64, i64) -> (FixedU64, FixedI64) }
|
||||
prim_convert! { (u64, i64, U64) -> (FixedU128, FixedI128, U128) }
|
||||
prim_to_fixed! { (u64, i64) -> (FixedU64, FixedI64) }
|
||||
prim_to_fixed! { (u64, i64, U64) -> (FixedU128, FixedI128, U128) }
|
||||
|
||||
prim_convert! { (u128, i128) -> (FixedU128, FixedI128) }
|
||||
prim_to_fixed! { (u128, i128) -> (FixedU128, FixedI128) }
|
||||
|
||||
macro_rules! fixed_to_prim {
|
||||
(($SrcU:ident, $SrcI:ident) -> ($DstU:ident, $DstI:ident)) => {
|
||||
impl From<$SrcU<U0>> for $DstU {
|
||||
#[inline]
|
||||
fn from(src: $SrcU<U0>) -> $DstU {
|
||||
src.to_bits()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$SrcI<U0>> for $DstI {
|
||||
#[inline]
|
||||
fn from(src: $SrcI<U0>) -> $DstI {
|
||||
src.to_bits()
|
||||
}
|
||||
}
|
||||
};
|
||||
(($SrcU:ident, $SrcI:ident) -> wider ($DstU:ident, $DstI:ident)) => {
|
||||
impl From<$SrcU<U0>> for $DstU {
|
||||
#[inline]
|
||||
fn from(src: $SrcU<U0>) -> $DstU {
|
||||
src.to_bits().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$SrcI<U0>> for $DstI {
|
||||
#[inline]
|
||||
fn from(src: $SrcI<U0>) -> $DstI {
|
||||
src.to_bits().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$SrcU<U0>> for $DstI {
|
||||
#[inline]
|
||||
fn from(src: $SrcU<U0>) -> $DstI {
|
||||
src.to_bits().into()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fixed_to_prim! { (FixedU8, FixedI8) -> (u8, i8) }
|
||||
fixed_to_prim! { (FixedU8, FixedI8) -> wider (u16, i16) }
|
||||
fixed_to_prim! { (FixedU8, FixedI8) -> wider (u32, i32) }
|
||||
fixed_to_prim! { (FixedU8, FixedI8) -> wider (u64, i64) }
|
||||
fixed_to_prim! { (FixedU8, FixedI8) -> wider (u128, i128) }
|
||||
|
||||
fixed_to_prim! { (FixedU16, FixedI16) -> (u16, i16) }
|
||||
fixed_to_prim! { (FixedU16, FixedI16) -> wider (u32, i32) }
|
||||
fixed_to_prim! { (FixedU16, FixedI16) -> wider (u64, i64) }
|
||||
fixed_to_prim! { (FixedU16, FixedI16) -> wider (u128, i128) }
|
||||
|
||||
fixed_to_prim! { (FixedU32, FixedI32) -> (u32, i32) }
|
||||
fixed_to_prim! { (FixedU32, FixedI32) -> wider (u64, i64) }
|
||||
fixed_to_prim! { (FixedU32, FixedI32) -> wider (u128, i128) }
|
||||
|
||||
fixed_to_prim! { (FixedU64, FixedI64) -> (u64, i64) }
|
||||
fixed_to_prim! { (FixedU64, FixedI64) -> wider (u128, i128) }
|
||||
|
||||
fixed_to_prim! { (FixedU128, FixedI128) -> (u128, i128) }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -214,6 +274,7 @@ mod tests {
|
|||
|
||||
let l = L8::from_bits(val);
|
||||
assert_eq!(l, L8::from(val));
|
||||
assert_eq!(val, u8::from(l));
|
||||
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
||||
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 8));
|
||||
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
||||
|
@ -248,6 +309,7 @@ mod tests {
|
|||
|
||||
let l = L8::from_bits(val);
|
||||
assert_eq!(l, L8::from(val));
|
||||
assert_eq!(val, i8::from(l));
|
||||
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
||||
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 8));
|
||||
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
||||
|
@ -282,6 +344,7 @@ mod tests {
|
|||
|
||||
let l = L8::from_bits(val);
|
||||
assert_eq!(l, L8::from(val));
|
||||
assert_eq!(val, u8::from(l));
|
||||
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
||||
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 7));
|
||||
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
||||
|
|
|
@ -42,6 +42,10 @@ fixed-point number lies in the range −0.5 ≤ *x* < 0.5 for signed
|
|||
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
|
||||
[`Into`] for the conversions that always work without losing any bits.
|
||||
|
||||
## Quick example
|
||||
|
||||
```rust
|
||||
|
@ -117,6 +121,7 @@ additional terms or conditions.
|
|||
[LICENSE-APACHE]: https://www.apache.org/licenses/LICENSE-2.0
|
||||
[LICENSE-MIT]: https://opensource.org/licenses/MIT
|
||||
[`FixedI128`]: struct.FixedI128.html
|
||||
[`FixedI128`]: struct.FixedI128.html
|
||||
[`FixedI16`]: struct.FixedI16.html
|
||||
[`FixedI32`]: struct.FixedI32.html
|
||||
[`FixedI64`]: struct.FixedI64.html
|
||||
|
@ -126,6 +131,8 @@ additional terms or conditions.
|
|||
[`FixedU32`]: struct.FixedU32.html
|
||||
[`FixedU64`]: struct.FixedU64.html
|
||||
[`FixedU8`]: struct.FixedU8.html
|
||||
[`From`]: https://doc.rust-lang.org/nightly/std/convert/trait.From.html
|
||||
[`Into`]: https://doc.rust-lang.org/nightly/std/convert/trait.Into.html
|
||||
[`f16`]: https://docs.rs/half/^1/half/struct.f16.html
|
||||
[const generics]: https://github.com/rust-lang/rust/issues/44580
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue