signum wraps in release mode

This commit is contained in:
Trevor Spiteri 2019-08-06 21:56:43 +02:00
parent 1a292a4245
commit b4baf7d15f
5 changed files with 39 additions and 45 deletions

View File

@ -16,7 +16,7 @@
use {
crate::{
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
sealed::{SealedFixed, SealedInt},
sealed::SealedInt,
wide_div::WideDivRem,
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
FixedU8,
@ -581,7 +581,7 @@ macro_rules! fixed_arith {
I: Iterator<Item = $Fixed<Frac>>,
{
match iter.next() {
None => Self::one().expect("overflow"),
None => 1.to_fixed(),
Some(first) => iter.fold(first, Mul::mul),
}
}
@ -596,7 +596,7 @@ macro_rules! fixed_arith {
I: Iterator<Item = &'a $Fixed<Frac>>,
{
match iter.next() {
None => Self::one().expect("overflow"),
None => 1.to_fixed(),
Some(first) => iter.fold(*first, Mul::mul),
}
}

View File

@ -563,12 +563,17 @@ assert_eq!(minus_five.abs(), five);
# Panics
This method panics:
When debug assertions are enabled, this method panics
* if the value is positive and the fixed-point number has zero
or one integer bits such that it cannot hold the value 1.
* if the value is negative and the fixed-point number has zero
integer bits, such that it cannot hold the value 1.
When debug assertions are not enabled, the wrapped value can be
returned in those cases, but it is not considered a breaking change if
in the future it panics; using this method when 1 and 1 cannot be
represented is almost certainly a bug.
# Examples
```rust
@ -584,8 +589,8 @@ assert_eq!(Fix::from_int(-5).signum(), -1);
pub fn signum(self) -> $Fixed<Frac> {
match self.to_bits().cmp(&0) {
Ordering::Equal => Self::from_bits(0),
Ordering::Greater => Self::one().expect("overflow"),
Ordering::Less => Self::minus_one().expect("overflow"),
Ordering::Greater => 1.to_fixed(),
Ordering::Less => (-1).to_fixed(),
}
}
);

View File

@ -94,27 +94,6 @@ pub trait SealedFixed: Copy + Debug + Default + Display + Eq + Hash + Ord {
where
F: SealedFloat;
#[inline]
fn one() -> Option<Self> {
let min_int_bits = if Self::SBits::IS_SIGNED { 2 } else { 1 };
if Self::INT_NBITS < min_int_bits {
None
} else {
Some(Self::from_sbits(Self::SBits::one_shl(Self::FRAC_NBITS)))
}
}
#[inline]
fn minus_one() -> Option<Self> {
if !Self::SBits::IS_SIGNED || Self::INT_NBITS < 1 {
None
} else {
Some(Self::from_sbits(Self::SBits::all_ones_shl(
Self::FRAC_NBITS,
)))
}
}
fn from_sbits(bits: Self::SBits) -> Self;
fn to_sbits(self) -> Self::SBits;
fn parts(

View File

@ -396,11 +396,17 @@ pub trait FixedSigned: Fixed {
///
/// # Panics
///
/// This method panics:
/// * if the value is positive and the fixed-point number has zero
/// or one integer bits such that it cannot hold the value 1.
/// * if the value is negative and the fixed-point number has zero
/// integer bits, such that it cannot hold the value 1.
/// When debug assertions are enabled, this method panics
/// * if the value is positive and the fixed-point number has
/// zero or one integer bits such that it cannot hold the
/// value 1.
/// * if the value is negative and the fixed-point number has
/// zero integer bits, such that it cannot hold the value 1.
///
/// When debug assertions are not enabled, the wrapped value can
/// be returned in those cases, but it is not considered a
/// breaking change if in the future it panics; using this method
/// when 1 and 1 cannot be represented is almost certainly a bug.
fn signum(self) -> Self;
/// Checked absolute value. Returns the absolute value, or [`None`] on overflow.

View File

@ -13,21 +13,25 @@
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.
use crate::frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8};
use crate::sealed::{Fixed, SealedFixed};
use crate::{
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
sealed::Fixed,
traits::ToFixed,
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
FixedU8,
};
use core::cmp::Ordering;
use core::default::Default;
use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
use core::hash::{Hash, Hasher};
use core::iter::{Product, Sum};
use core::num::Wrapping as CoreWrapping;
use core::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
use core::{
cmp::Ordering,
default::Default,
fmt::{Debug, Display, Formatter, Result as FmtResult},
hash::{Hash, Hasher},
iter::{Product, Sum},
num::Wrapping as CoreWrapping,
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
SubAssign,
},
};
/// Provides intentionally wrapped arithmetic on fixed-point numbers.
@ -507,7 +511,7 @@ macro_rules! ops {
I: Iterator<Item = Wrapping<$Fixed<Frac>>>,
{
match iter.next() {
None => Wrapping($Fixed::one().unwrap_or_else(|| $Fixed::from_bits(0))),
None => Wrapping(1.wrapping_to_fixed()),
Some(first) => iter.fold(first, Mul::mul),
}
}
@ -522,7 +526,7 @@ macro_rules! ops {
I: Iterator<Item = &'a Wrapping<$Fixed<Frac>>>,
{
match iter.next() {
None => Wrapping($Fixed::one().unwrap_or_else(|| $Fixed::from_bits(0))),
None => Wrapping(1.wrapping_to_fixed()),
Some(first) => iter.fold(*first, Mul::mul),
}
}