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, and in the range 0 ≤ *x* < 1 for unsigned
|
||||||
fixed-point numbers.
|
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
|
## 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)
|
### Version 0.1.4 news (2018-11-29)
|
||||||
|
|
||||||
* Division is now implemented for [`FixedI128`] and [`FixedU128`].
|
* 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
|
[`FixedU32`]: https://docs.rs/fixed/0.1.4/fixed/struct.FixedU32.html
|
||||||
[`FixedU64`]: https://docs.rs/fixed/0.1.4/fixed/struct.FixedU64.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
|
[`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
|
[`f16`]: https://docs.rs/half/^1/half/struct.f16.html
|
||||||
[const generics]: https://github.com/rust-lang/rust/issues/44580
|
[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
|
copyright notice and this notice are preserved. This file is offered
|
||||||
as-is, without any warranty. -->
|
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)
|
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) }
|
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)) => {
|
(($SrcU:ident, $SrcI:ident, $SrcBits:ident) -> ($DstU:ident, $DstI:ident, $DstBits:ident)) => {
|
||||||
// Condition: FracDst <= $DstBits - $SrcBits
|
// Condition: FracDst <= $DstBits - $SrcBits
|
||||||
impl<FracDst> From<$SrcU> for $DstU<FracDst>
|
impl<FracDst> From<$SrcU> for $DstU<FracDst>
|
||||||
|
@ -169,25 +169,85 @@ macro_rules! prim_convert {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
prim_convert! { (u8, i8) -> (FixedU8, FixedI8) }
|
prim_to_fixed! { (u8, i8) -> (FixedU8, FixedI8) }
|
||||||
prim_convert! { (u8, i8, U8) -> (FixedU16, FixedI16, U16) }
|
prim_to_fixed! { (u8, i8, U8) -> (FixedU16, FixedI16, U16) }
|
||||||
prim_convert! { (u8, i8, U8) -> (FixedU32, FixedI32, U32) }
|
prim_to_fixed! { (u8, i8, U8) -> (FixedU32, FixedI32, U32) }
|
||||||
prim_convert! { (u8, i8, U8) -> (FixedU64, FixedI64, U64) }
|
prim_to_fixed! { (u8, i8, U8) -> (FixedU64, FixedI64, U64) }
|
||||||
prim_convert! { (u8, i8, U8) -> (FixedU128, FixedI128, U128) }
|
prim_to_fixed! { (u8, i8, U8) -> (FixedU128, FixedI128, U128) }
|
||||||
|
|
||||||
prim_convert! { (u16, i16) -> (FixedU16, FixedI16) }
|
prim_to_fixed! { (u16, i16) -> (FixedU16, FixedI16) }
|
||||||
prim_convert! { (u16, i16, U16) -> (FixedU32, FixedI32, U32) }
|
prim_to_fixed! { (u16, i16, U16) -> (FixedU32, FixedI32, U32) }
|
||||||
prim_convert! { (u16, i16, U16) -> (FixedU64, FixedI64, U64) }
|
prim_to_fixed! { (u16, i16, U16) -> (FixedU64, FixedI64, U64) }
|
||||||
prim_convert! { (u16, i16, U16) -> (FixedU128, FixedI128, U128) }
|
prim_to_fixed! { (u16, i16, U16) -> (FixedU128, FixedI128, U128) }
|
||||||
|
|
||||||
prim_convert! { (u32, i32) -> (FixedU32, FixedI32) }
|
prim_to_fixed! { (u32, i32) -> (FixedU32, FixedI32) }
|
||||||
prim_convert! { (u32, i32, U32) -> (FixedU64, FixedI64, U64) }
|
prim_to_fixed! { (u32, i32, U32) -> (FixedU64, FixedI64, U64) }
|
||||||
prim_convert! { (u32, i32, U32) -> (FixedU128, FixedI128, U128) }
|
prim_to_fixed! { (u32, i32, U32) -> (FixedU128, FixedI128, U128) }
|
||||||
|
|
||||||
prim_convert! { (u64, i64) -> (FixedU64, FixedI64) }
|
prim_to_fixed! { (u64, i64) -> (FixedU64, FixedI64) }
|
||||||
prim_convert! { (u64, i64, U64) -> (FixedU128, FixedI128, U128) }
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -214,6 +274,7 @@ mod tests {
|
||||||
|
|
||||||
let l = L8::from_bits(val);
|
let l = L8::from_bits(val);
|
||||||
assert_eq!(l, L8::from(val));
|
assert_eq!(l, L8::from(val));
|
||||||
|
assert_eq!(val, u8::from(l));
|
||||||
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
||||||
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 8));
|
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 8));
|
||||||
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
||||||
|
@ -248,6 +309,7 @@ mod tests {
|
||||||
|
|
||||||
let l = L8::from_bits(val);
|
let l = L8::from_bits(val);
|
||||||
assert_eq!(l, L8::from(val));
|
assert_eq!(l, L8::from(val));
|
||||||
|
assert_eq!(val, i8::from(l));
|
||||||
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
||||||
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 8));
|
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 8));
|
||||||
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
||||||
|
@ -282,6 +344,7 @@ mod tests {
|
||||||
|
|
||||||
let l = L8::from_bits(val);
|
let l = L8::from_bits(val);
|
||||||
assert_eq!(l, L8::from(val));
|
assert_eq!(l, L8::from(val));
|
||||||
|
assert_eq!(val, u8::from(l));
|
||||||
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
assert_eq!(LL16::from(l), LL16::from_bits(val16));
|
||||||
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 7));
|
assert_eq!(LH16::from(l), LH16::from_bits(val16 << 7));
|
||||||
assert_eq!(LL128::from(l), LL128::from_bits(val128));
|
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, and in the range 0 ≤ *x* < 1 for unsigned
|
||||||
fixed-point numbers.
|
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
|
## Quick example
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -117,6 +121,7 @@ additional terms or conditions.
|
||||||
[LICENSE-APACHE]: https://www.apache.org/licenses/LICENSE-2.0
|
[LICENSE-APACHE]: https://www.apache.org/licenses/LICENSE-2.0
|
||||||
[LICENSE-MIT]: https://opensource.org/licenses/MIT
|
[LICENSE-MIT]: https://opensource.org/licenses/MIT
|
||||||
[`FixedI128`]: struct.FixedI128.html
|
[`FixedI128`]: struct.FixedI128.html
|
||||||
|
[`FixedI128`]: struct.FixedI128.html
|
||||||
[`FixedI16`]: struct.FixedI16.html
|
[`FixedI16`]: struct.FixedI16.html
|
||||||
[`FixedI32`]: struct.FixedI32.html
|
[`FixedI32`]: struct.FixedI32.html
|
||||||
[`FixedI64`]: struct.FixedI64.html
|
[`FixedI64`]: struct.FixedI64.html
|
||||||
|
@ -126,6 +131,8 @@ additional terms or conditions.
|
||||||
[`FixedU32`]: struct.FixedU32.html
|
[`FixedU32`]: struct.FixedU32.html
|
||||||
[`FixedU64`]: struct.FixedU64.html
|
[`FixedU64`]: struct.FixedU64.html
|
||||||
[`FixedU8`]: struct.FixedU8.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
|
[`f16`]: https://docs.rs/half/^1/half/struct.f16.html
|
||||||
[const generics]: https://github.com/rust-lang/rust/issues/44580
|
[const generics]: https://github.com/rust-lang/rust/issues/44580
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue