add methods: {from,to}_{be,le}, swap_bytes, reverse_bits

This commit is contained in:
Trevor Spiteri 2021-02-24 13:31:40 +01:00
parent d08b8eb8cb
commit 25655ae215
4 changed files with 161 additions and 13 deletions

View File

@ -81,11 +81,21 @@ The conversions supported cover the following cases.
### Version 1.7.0 news (unreleased)
* The following methods were added to all fixed-point numbers:
* [`from_be`][f-fb-1-7], [`from_le`][f-fl-1-7]
* [`to_be`][f-tb-1-7], [`to_le`][f-tl-1-7]
* [`swap_bytes`][f-sb-1-7], [`reverse_bits`][f-rb-1-7]
* For the experimental feature [`num-traits`][feat-exp-1-7], the
following traits were implemented where applicable:
* [`OverflowingAdd`][nt-0-2-oa], [`OverflowingSub`][nt-0-2-os],
[`OverflowingMul`][nt-0-2-om]
[f-fb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.from_be
[f-fl-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.from_le
[f-rb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.reverse_bits
[f-sb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.swap_bytes
[f-tb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.to_be
[f-tl-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.to_le
[feat-exp-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/#experimental-optional-features
[nt-0-2-oa]: https://docs.rs/num-traits/^0.2/num_traits/ops/overflowing/trait.OverflowingAdd.html
[nt-0-2-om]: https://docs.rs/num-traits/^0.2/num_traits/ops/overflowing/trait.OverflowingMul.html

View File

@ -8,11 +8,21 @@ as-is, without any warranty. -->
Version 1.7.0 (unreleased)
==========================
* The following methods were added to all fixed-point numbers:
* [`from_be`][f-fb-1-7], [`from_le`][f-fl-1-7]
* [`to_be`][f-tb-1-7], [`to_le`][f-tl-1-7]
* [`swap_bytes`][f-sb-1-7], [`reverse_bits`][f-rb-1-7]
* For the experimental feature [`num-traits`][feat-exp-1-7], the
following traits were implemented where applicable:
* [`OverflowingAdd`][nt-0-2-oa], [`OverflowingSub`][nt-0-2-os],
[`OverflowingMul`][nt-0-2-om]
[f-fb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.from_be
[f-fl-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.from_le
[f-rb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.reverse_bits
[f-sb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.swap_bytes
[f-tb-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.to_be
[f-tl-1-7]: https://docs.rs/fixed/~1.6/fixed/struct.FixedI32.html#method.to_le
[feat-exp-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/#experimental-optional-features
[nt-0-2-oa]: https://docs.rs/num-traits/^0.2/num_traits/ops/overflowing/trait.OverflowingAdd.html
[nt-0-2-om]: https://docs.rs/num-traits/^0.2/num_traits/ops/overflowing/trait.OverflowingMul.html

View File

@ -377,7 +377,7 @@ macro_rules! fixed {
$Inner:ty, $LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$nbytes:expr, $bytes_val:expr, $rev_bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UFixed:ident, $UInner:ty, $Signedness:tt,
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt,
$Double:ident, $DoubleInner:ty, $HasDouble:tt
@ -388,7 +388,7 @@ macro_rules! fixed {
$Inner[stringify!($Inner)], $LeEqU, $s_nbits,
$s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4
),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$nbytes, $bytes_val, $rev_bytes_val, $be_bytes, $le_bytes,
$UFixed[stringify!($UFixed)], $UInner, $Signedness,
$LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3,
$Double, $DoubleInner, $HasDouble
@ -400,7 +400,7 @@ macro_rules! fixed {
$Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$nbytes:expr, $bytes_val:expr, $rev_bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UFixed:ident[$s_ufixed:expr], $UInner:ty, $Signedness:tt,
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt,
$Double:ident, $DoubleInner:ty, $HasDouble:tt
@ -470,7 +470,7 @@ assert_eq!(two_point_75.to_string(), \"2.8\");
// inherent methods that do not require Frac bounds, some of which can thus be const
fixed_no_frac! {
$Fixed[$s_fixed]($Inner[$s_inner], $LeEqU, $s_nbits),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$nbytes, $bytes_val, $rev_bytes_val, $be_bytes, $le_bytes,
$UFixed[$s_ufixed], $UInner, $Signedness,
$Double, $DoubleInner, $HasDouble
}
@ -490,7 +490,7 @@ assert_eq!(two_point_75.to_string(), \"2.8\");
fixed! {
"An eight-bit fixed-point unsigned",
FixedU8(u8, LeEqU8, "8", "7", "6", "5", "4"),
1, "0x12", "[0x12]", "[0x12]",
1, "0x12", "0x12", "[0x12]", "[0x12]",
FixedU8, u8, Unsigned,
U8, U7, U6, U5,
FixedU16, u16, True
@ -498,7 +498,7 @@ fixed! {
fixed! {
"A 16-bit fixed-point unsigned",
FixedU16(u16, LeEqU16, "16", "15", "14", "13", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
2, "0x1234", "0x3412", "[0x12, 0x34]", "[0x34, 0x12]",
FixedU16, u16, Unsigned,
U16, U15, U14, U13,
FixedU32, u32, True
@ -506,7 +506,7 @@ fixed! {
fixed! {
"A 32-bit fixed-point unsigned",
FixedU32(u32, LeEqU32, "32", "31", "30", "29", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
4, "0x1234_5678", "0x7856_3412", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
FixedU32, u32, Unsigned,
U32, U31, U30, U29,
FixedU64, u64, True
@ -514,7 +514,7 @@ fixed! {
fixed! {
"A 64-bit fixed-point unsigned",
FixedU64(u64, LeEqU64, "64", "63", "62", "61", "60"),
8, "0x1234_5678_9ABC_DEF0",
8, "0x1234_5678_9ABC_DEF0", "0xF0DE_BC8A_7856_3412",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedU64, u64, Unsigned,
@ -525,6 +525,7 @@ fixed! {
"A 128-bit fixed-point unsigned",
FixedU128(u128, LeEqU128, "128", "127", "126", "125", "124"),
16, "0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0",
"0xF0DE_BC9A_7856_3412_F0DE_BC9A_7856_3412",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, \
@ -536,7 +537,7 @@ fixed! {
fixed! {
"An eight-bit fixed-point signed",
FixedI8(i8, LeEqU8, "8", "7", "6", "5", "4"),
1, "0x12", "[0x12]", "[0x12]",
1, "0x12", "0x12", "[0x12]", "[0x12]",
FixedU8, u8, Signed,
U7, U6, U5, U4,
FixedI16, i16, True
@ -544,7 +545,7 @@ fixed! {
fixed! {
"A 16-bit fixed-point signed",
FixedI16(i16, LeEqU16, "16", "15", "14", "13", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
2, "0x1234", "0x3412", "[0x12, 0x34]", "[0x34, 0x12]",
FixedU16, u16, Signed,
U15, U14, U13, U12,
FixedI32, i32, True
@ -552,7 +553,7 @@ fixed! {
fixed! {
"A 32-bit fixed-point signed",
FixedI32(i32, LeEqU32, "32", "31", "30", "29", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
4, "0x1234_5678", "0x7856_3412", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
FixedU32, u32, Signed,
U31, U30, U29, U28,
FixedI64, i64, True
@ -560,7 +561,7 @@ fixed! {
fixed! {
"A 64-bit fixed-point signed",
FixedI64(i64, LeEqU64, "64", "63", "62", "61", "60"),
8, "0x1234_5678_9ABC_DEF0",
8, "0x1234_5678_9ABC_DEF0", "0xF0DE_BC8A_7856_3412",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedU64, u64, Signed,
@ -571,6 +572,7 @@ fixed! {
"A 128-bit fixed-point signed",
FixedI128(i128, LeEqU128, "128", "127", "126", "125", "124"),
16, "0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0",
"0xF0DE_BC9A_7856_3412_F0DE_BC9A_7856_3412",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, \

View File

@ -16,7 +16,7 @@
macro_rules! fixed_no_frac {
(
$Fixed:ident[$s_fixed:expr]($Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$nbytes:expr, $bytes_val:expr, $rev_bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UFixed:ident[$s_ufixed:expr], $UInner:ty, $Signedness:tt,
$Double:ident, $DoubleInner:ty, $HasDouble:tt
) => {
@ -92,6 +92,113 @@ assert_eq!(Fix::from_num(2).to_bits(), 0b10_0000);
}
}
comment! {
"Converts a fixed-point number from big endian to the targets endianness.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
let f = Fix::from_bits(", $bytes_val, ");
if cfg!(target_endian = \"big\") {
assert_eq!(Fix::from_be(f), f);
} else {
assert_eq!(Fix::from_be(f), f.swap_bytes());
}
```
";
#[inline]
pub const fn from_be(f: $Fixed<Frac>) -> $Fixed<Frac> {
$Fixed::from_bits(<$Inner>::from_be(f.to_bits()))
}
}
comment! {
"Converts a fixed-point number from little endian to the targets endianness.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
let f = Fix::from_bits(", $bytes_val, ");
if cfg!(target_endian = \"little\") {
assert_eq!(Fix::from_le(f), f);
} else {
assert_eq!(Fix::from_le(f), f.swap_bytes());
}
```
";
#[inline]
pub const fn from_le(f: $Fixed<Frac>) -> $Fixed<Frac> {
$Fixed::from_bits(<$Inner>::from_le(f.to_bits()))
}
}
comment! {
"Converts `self` to big endian from the targets endianness.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
let f = Fix::from_bits(", $bytes_val, ");
if cfg!(target_endian = \"big\") {
assert_eq!(f.to_be(), f);
} else {
assert_eq!(f.to_be(), f.swap_bytes());
}
```
";
#[inline]
pub const fn to_be(self) -> $Fixed<Frac> {
$Fixed::from_bits(self.to_bits().to_be())
}
}
comment! {
"Converts `self` to little endian from the targets endianness.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
let f = Fix::from_bits(", $bytes_val, ");
if cfg!(target_endian = \"little\") {
assert_eq!(f.to_le(), f);
} else {
assert_eq!(f.to_le(), f.swap_bytes());
}
```
";
#[inline]
pub const fn to_le(self) -> $Fixed<Frac> {
$Fixed::from_bits(self.to_bits().to_le())
}
}
comment! {
"Reverses the byte order of the fixed-point number.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
let f = Fix::from_bits(", $bytes_val, ");
let rev = Fix::from_bits(", $rev_bytes_val, ");
assert_eq!(f.swap_bytes(), rev);
```
";
#[inline]
pub const fn swap_bytes(self) -> $Fixed<Frac> {
$Fixed::from_bits(self.to_bits().swap_bytes())
}
}
comment! {
"Creates a fixed-point number from its representation
as a byte array in big endian.
@ -344,6 +451,25 @@ assert_eq!(f.trailing_zeros(), 5);
}
}
comment! {
"Reverses the order of the bits of the fixed-point number.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
let bits = ", $bytes_val, "_", $s_inner, ";
let rev_bits = bits.reverse_bits();
assert_eq!(Fix::from_bits(bits).reverse_bits(), Fix::from_bits(rev_bits));
```
";
#[inline]
pub const fn reverse_bits(self) -> $Fixed<Frac> {
$Fixed::from_bits(self.to_bits().reverse_bits())
}
}
comment! {
"Shifts to the left by `n` bits, wrapping the
truncated bits to the right end.