From ca7c39505dfaeace4acbdb1017685c248c5f2172 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Wed, 7 Apr 2021 22:13:57 +0200 Subject: [PATCH] update docs with delta information --- README.md | 20 +++++++++--- src/lib.rs | 76 +++++++++++++++++++++++++++++++++---------- src/macros_no_frac.rs | 32 +++++++++--------- src/traits.rs | 8 ++--- src/unwrapped.rs | 20 ++++++------ src/wrapping.rs | 20 ++++++------ 6 files changed, 115 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 666f64c..553445f 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,22 @@ The [*fixed* crate] provides fixed-point numbers. * [`FixedI64`] and [`FixedU64`] are 64-bit fixed-point numbers. * [`FixedI128`] and [`FixedU128`] are 128-bit fixed-point numbers. -These types can have `Frac` fractional bits, where -0 ≤ `Frac` ≤ n and n is the total number of bits. When -`Frac` = 0, the fixed-point number behaves like an n-bit -integer. When `Frac` = n, the value x lies in the range +These types can have f = `Frac` fractional bits, where +0 ≤ f ≤ n and n is the total number of bits. For +example, [`FixedI32`] is a 32-bit signed fixed-point number with +n = 32. The value x can lie in the range +−2n − f − 1 ≤ x < 2n − f − 1 +for signed numbers, and in the range +0 ≤ x < 2n − f for unsigned numbers. The +difference between successive numbers is constant throughout the +range: Δ = 2f. + +When f = 0, Δ = 1 and the fixed-point number behaves +like an n-bit integer with the value lying in the range +−2n − 1 ≤ x < 2n − 1 for signed +numbers, and in the range 0 ≤ x < 2n for +unsigned numbers. When f = n, +Δ = 2n and the value lies in the range −0.5 ≤ x < 0.5 for signed numbers, and in the range 0 ≤ x < 1 for unsigned numbers. diff --git a/src/lib.rs b/src/lib.rs index 013ccb5..e1b8395 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,10 +24,22 @@ The [*fixed* crate] provides fixed-point numbers. * [`FixedI64`] and [`FixedU64`] are 64-bit fixed-point numbers. * [`FixedI128`] and [`FixedU128`] are 128-bit fixed-point numbers. -These types can have `Frac` fractional bits, where -0 ≤ `Frac` ≤ n and n is the total number of bits. When -`Frac` = 0, the fixed-point number behaves like an n-bit -integer. When `Frac` = n, the value x lies in the range +These types can have f = `Frac` fractional bits, where +0 ≤ f ≤ n and n is the total number of bits. For +example, [`FixedI32`] is a 32-bit signed fixed-point number with +n = 32. The value x can lie in the range +−2n − f − 1 ≤ x < 2n − f − 1 +for signed numbers, and in the range +0 ≤ x < 2n − f for unsigned numbers. The +difference between successive numbers is constant throughout the +range: Δ = 2f. + +When f = 0, Δ = 1 and the fixed-point number behaves +like an n-bit integer with the value lying in the range +−2n − 1 ≤ x < 2n − 1 for signed +numbers, and in the range 0 ≤ x < 2n for +unsigned numbers. When f = n, +Δ = 2n and the value lies in the range −0.5 ≤ x < 0.5 for signed numbers, and in the range 0 ≤ x < 1 for unsigned numbers. @@ -401,12 +413,42 @@ macro_rules! fixed { $Double:ident, $DoubleInner:ty, $HasDouble:tt ) => { comment! { - $description, + $description, "-bit ", + if_signed_unsigned!($Signedness, "signed", "unsigned"), " number with `Frac` fractional bits. +The number has ", $s_nbits, " bits, of which f = `Frac` are +fractional bits and ", $s_nbits, " − f are integer bits. The +value x can lie in the range ", + if_signed_unsigned!( + $Signedness, + concat!("−2", $s_nbits_m1, " − f"), + "0", + ), + " ≤ x < 2", + if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits), + " − f. The difference between successive +numbers is constant throughout the range: +Δ = 2f. + +When f = 0, Δ = 1 and the fixed-point number behaves +like an ", $s_nbits, "-bit integer ([`", $s_inner, "`]) with the value +lying in the range ", + if_signed_unsigned!( + $Signedness, + concat!("−2", $s_nbits_m1, ""), + "0", + ), + " ≤ x < 2", + if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits), + ". When f = ", $s_nbits, ", +Δ = 2−", $s_nbits, " and the value lies in the range ", + if_signed_unsigned!($Signedness, "−0.5 ≤ x < 0.5", "0 ≤ x < 1"), + ". + `Frac` is an [`Unsigned`] as provided by the [*typenum* crate]; the -plan is to move to [const generics] in version 2 when they are -supported by the Rust compiler. +plan is to to have a major version 2 with [const generics] instead +when the Rust compiler support for them is powerful enough. # Examples @@ -482,7 +524,7 @@ assert_eq!(two_point_75.to_string(), \"2.8\"); } fixed! { - "An eight-bit fixed-point unsigned", + "An eight", FixedU8(u8, LeEqU8, "8", "7", "6", "5", "4"), 1, "0x12", "0x12", "[0x12]", "[0x12]", FixedU8, u8, Unsigned, @@ -490,7 +532,7 @@ fixed! { FixedU16, u16, True } fixed! { - "A 16-bit fixed-point unsigned", + "A 16", FixedU16(u16, LeEqU16, "16", "15", "14", "13", "12"), 2, "0x1234", "0x3412", "[0x12, 0x34]", "[0x34, 0x12]", FixedU16, u16, Unsigned, @@ -498,7 +540,7 @@ fixed! { FixedU32, u32, True } fixed! { - "A 32-bit fixed-point unsigned", + "A 32", FixedU32(u32, LeEqU32, "32", "31", "30", "29", "28"), 4, "0x1234_5678", "0x7856_3412", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]", FixedU32, u32, Unsigned, @@ -506,7 +548,7 @@ fixed! { FixedU64, u64, True } fixed! { - "A 64-bit fixed-point unsigned", + "A 64", FixedU64(u64, LeEqU64, "64", "63", "62", "61", "60"), 8, "0x1234_5678_9ABC_DE0F", "0x0FDE_BC9A_7856_3412", "[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0x0F]", @@ -516,7 +558,7 @@ fixed! { FixedU128, u128, True } fixed! { - "A 128-bit fixed-point unsigned", + "A 128", FixedU128(u128, LeEqU128, "128", "127", "126", "125", "124"), 16, "0x1234_5678_9ABC_DEF0_0102_0304_0506_0708", "0x0807_0605_0403_0201_F0DE_BC9A_7856_3412", @@ -529,7 +571,7 @@ fixed! { FixedU128, u128, False } fixed! { - "An eight-bit fixed-point signed", + "An eight", FixedI8(i8, LeEqU8, "8", "7", "6", "5", "4"), 1, "0x12", "0x12", "[0x12]", "[0x12]", FixedU8, u8, Signed, @@ -537,7 +579,7 @@ fixed! { FixedI16, i16, True } fixed! { - "A 16-bit fixed-point signed", + "A 16", FixedI16(i16, LeEqU16, "16", "15", "14", "13", "12"), 2, "0x1234", "0x3412", "[0x12, 0x34]", "[0x34, 0x12]", FixedU16, u16, Signed, @@ -545,7 +587,7 @@ fixed! { FixedI32, i32, True } fixed! { - "A 32-bit fixed-point signed", + "A 32", FixedI32(i32, LeEqU32, "32", "31", "30", "29", "28"), 4, "0x1234_5678", "0x7856_3412", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]", FixedU32, u32, Signed, @@ -553,7 +595,7 @@ fixed! { FixedI64, i64, True } fixed! { - "A 64-bit fixed-point signed", + "A 64", FixedI64(i64, LeEqU64, "64", "63", "62", "61", "60"), 8, "0x1234_5678_9ABC_DE0F", "0x0FDE_BC9A_7856_3412", "[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0x0F]", @@ -563,7 +605,7 @@ fixed! { FixedI128, i128, True } fixed! { - "A 128-bit fixed-point signed", + "A 128", FixedI128(i128, LeEqU128, "128", "127", "126", "125", "124"), 16, "0x1234_5678_9ABC_DEF0_0102_0304_0506_0708", "0x0807_0605_0403_0201_F0DE_BC9A_7856_3412", diff --git a/src/macros_no_frac.rs b/src/macros_no_frac.rs index e381c9c..01cf3fd 100644 --- a/src/macros_no_frac.rs +++ b/src/macros_no_frac.rs @@ -37,6 +37,22 @@ assert_eq!(Fix::ZERO, Fix::from_bits(0)); pub const ZERO: $Fixed = Self::from_bits(0); } + comment! { + "The difference between any two successive representable numbers, Δ. + +# Examples + +```rust +use fixed::{types::extra::U4, ", $s_fixed, "}; +type Fix = ", $s_fixed, "; +assert_eq!(Fix::DELTA, Fix::from_bits(1)); +// binary 0.0001 is decimal 0.0625 +assert_eq!(Fix::DELTA, 0.0625); +``` +"; + pub const DELTA: $Fixed = Self::from_bits(1); + } + comment! { "The smallest value that can be represented. @@ -65,22 +81,6 @@ assert_eq!(Fix::MAX, Fix::from_bits(", $s_inner, "::MAX)); pub const MAX: $Fixed = Self::from_bits(<$Inner>::MAX); } - comment! { - "The smallest positive value that can be represented. - -# Examples - -```rust -use fixed::{types::extra::U4, ", $s_fixed, "}; -type Fix = ", $s_fixed, "; -assert_eq!(Fix::DELTA, Fix::from_bits(1)); -// binary 0.0001 is decimal 0.0625 -assert_eq!(Fix::DELTA, 0.0625); -``` -"; - pub const DELTA: $Fixed = Self::from_bits(1); - } - comment! { if_signed_unsigned!($Signedness, "[`true`]", "[`false`]"), "[`bool`] because the [`", $s_fixed, "`] type is ", diff --git a/src/traits.rs b/src/traits.rs index c8c75a3..1dad7e0 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -304,15 +304,15 @@ where /// Zero. const ZERO: Self; + /// The difference between any two successive representable numbers, Δ. + const DELTA: Self; + /// The smallest value that can be represented. const MIN: Self; /// The largest value that can be represented. const MAX: Self; - /// The smallest positive value that can be represented. - const DELTA: Self; - /// [`true`] if the type is signed. const IS_SIGNED: bool; @@ -2258,9 +2258,9 @@ macro_rules! impl_fixed { type Bytes = [u8; mem::size_of::<$Bits>()]; type Frac = Frac; const ZERO: Self = Self::ZERO; + const DELTA: Self = Self::DELTA; const MIN: Self = Self::MIN; const MAX: Self = Self::MAX; - const DELTA: Self = Self::DELTA; const IS_SIGNED: bool = Self::IS_SIGNED; const INT_NBITS: u32 = Self::INT_NBITS; const FRAC_NBITS: u32 = Self::FRAC_NBITS; diff --git a/src/unwrapped.rs b/src/unwrapped.rs index f1a7bcc..70a0fd1 100644 --- a/src/unwrapped.rs +++ b/src/unwrapped.rs @@ -62,6 +62,16 @@ impl Unwrapped { /// ``` pub const ZERO: Unwrapped = Unwrapped(F::ZERO); + /// The difference between any two successive representable numbers, Δ. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{types::I16F16, Unwrapped}; + /// assert_eq!(Unwrapped::::DELTA, Unwrapped(I16F16::DELTA)); + /// ``` + pub const DELTA: Unwrapped = Unwrapped(F::DELTA); + /// The smallest value that can be represented. /// /// # Examples @@ -82,16 +92,6 @@ impl Unwrapped { /// ``` pub const MAX: Unwrapped = Unwrapped(F::MAX); - /// The smallest positive value that can be represented. - /// - /// # Examples - /// - /// ```rust - /// use fixed::{types::I16F16, Unwrapped}; - /// assert_eq!(Unwrapped::::DELTA, Unwrapped(I16F16::DELTA)); - /// ``` - pub const DELTA: Unwrapped = Unwrapped(F::DELTA); - /// [`true`] if the type is signed. /// /// # Examples diff --git a/src/wrapping.rs b/src/wrapping.rs index 72f695d..48fce95 100644 --- a/src/wrapping.rs +++ b/src/wrapping.rs @@ -59,6 +59,16 @@ impl Wrapping { /// ``` pub const ZERO: Wrapping = Wrapping(F::ZERO); + /// The difference between any two successive representable numbers, Δ. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{types::I16F16, Wrapping}; + /// assert_eq!(Wrapping::::DELTA, Wrapping(I16F16::DELTA)); + /// ``` + pub const DELTA: Wrapping = Wrapping(F::DELTA); + /// The smallest value that can be represented. /// /// # Examples @@ -79,16 +89,6 @@ impl Wrapping { /// ``` pub const MAX: Wrapping = Wrapping(F::MAX); - /// The smallest positive value that can be represented. - /// - /// # Examples - /// - /// ```rust - /// use fixed::{types::I16F16, Wrapping}; - /// assert_eq!(Wrapping::::DELTA, Wrapping(I16F16::DELTA)); - /// ``` - pub const DELTA: Wrapping = Wrapping(F::DELTA); - /// [`true`] if the type is signed. /// /// # Examples