signum wraps in release mode
This commit is contained in:
parent
1a292a4245
commit
b4baf7d15f
|
@ -16,7 +16,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
|
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
|
||||||
sealed::{SealedFixed, SealedInt},
|
sealed::SealedInt,
|
||||||
wide_div::WideDivRem,
|
wide_div::WideDivRem,
|
||||||
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
|
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
|
||||||
FixedU8,
|
FixedU8,
|
||||||
|
@ -581,7 +581,7 @@ macro_rules! fixed_arith {
|
||||||
I: Iterator<Item = $Fixed<Frac>>,
|
I: Iterator<Item = $Fixed<Frac>>,
|
||||||
{
|
{
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
None => Self::one().expect("overflow"),
|
None => 1.to_fixed(),
|
||||||
Some(first) => iter.fold(first, Mul::mul),
|
Some(first) => iter.fold(first, Mul::mul),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ macro_rules! fixed_arith {
|
||||||
I: Iterator<Item = &'a $Fixed<Frac>>,
|
I: Iterator<Item = &'a $Fixed<Frac>>,
|
||||||
{
|
{
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
None => Self::one().expect("overflow"),
|
None => 1.to_fixed(),
|
||||||
Some(first) => iter.fold(*first, Mul::mul),
|
Some(first) => iter.fold(*first, Mul::mul),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
src/lib.rs
11
src/lib.rs
|
@ -563,12 +563,17 @@ assert_eq!(minus_five.abs(), five);
|
||||||
|
|
||||||
# Panics
|
# Panics
|
||||||
|
|
||||||
This method panics:
|
When debug assertions are enabled, this method panics
|
||||||
* if the value is positive and the fixed-point number has zero
|
* if the value is positive and the fixed-point number has zero
|
||||||
or one integer bits such that it cannot hold the value 1.
|
or one integer bits such that it cannot hold the value 1.
|
||||||
* if the value is negative and the fixed-point number has zero
|
* if the value is negative and the fixed-point number has zero
|
||||||
integer bits, such that it cannot hold the value −1.
|
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
|
# Examples
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -584,8 +589,8 @@ assert_eq!(Fix::from_int(-5).signum(), -1);
|
||||||
pub fn signum(self) -> $Fixed<Frac> {
|
pub fn signum(self) -> $Fixed<Frac> {
|
||||||
match self.to_bits().cmp(&0) {
|
match self.to_bits().cmp(&0) {
|
||||||
Ordering::Equal => Self::from_bits(0),
|
Ordering::Equal => Self::from_bits(0),
|
||||||
Ordering::Greater => Self::one().expect("overflow"),
|
Ordering::Greater => 1.to_fixed(),
|
||||||
Ordering::Less => Self::minus_one().expect("overflow"),
|
Ordering::Less => (-1).to_fixed(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -94,27 +94,6 @@ pub trait SealedFixed: Copy + Debug + Default + Display + Eq + Hash + Ord {
|
||||||
where
|
where
|
||||||
F: SealedFloat;
|
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 from_sbits(bits: Self::SBits) -> Self;
|
||||||
fn to_sbits(self) -> Self::SBits;
|
fn to_sbits(self) -> Self::SBits;
|
||||||
fn parts(
|
fn parts(
|
||||||
|
|
|
@ -396,11 +396,17 @@ pub trait FixedSigned: Fixed {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// This method panics:
|
/// When debug assertions are enabled, this method panics
|
||||||
/// * if the value is positive and the fixed-point number has zero
|
/// * if the value is positive and the fixed-point number has
|
||||||
/// or one integer bits such that it cannot hold the value 1.
|
/// zero or one integer bits such that it cannot hold the
|
||||||
/// * if the value is negative and the fixed-point number has zero
|
/// value 1.
|
||||||
/// 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;
|
fn signum(self) -> Self;
|
||||||
|
|
||||||
/// Checked absolute value. Returns the absolute value, or [`None`] on overflow.
|
/// Checked absolute value. Returns the absolute value, or [`None`] on overflow.
|
||||||
|
|
|
@ -13,21 +13,25 @@
|
||||||
// <https://www.apache.org/licenses/LICENSE-2.0> and
|
// <https://www.apache.org/licenses/LICENSE-2.0> and
|
||||||
// <https://opensource.org/licenses/MIT>.
|
// <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
use crate::frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8};
|
|
||||||
use crate::sealed::{Fixed, SealedFixed};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
|
||||||
|
sealed::Fixed,
|
||||||
|
traits::ToFixed,
|
||||||
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
|
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
|
||||||
FixedU8,
|
FixedU8,
|
||||||
};
|
};
|
||||||
use core::cmp::Ordering;
|
use core::{
|
||||||
use core::default::Default;
|
cmp::Ordering,
|
||||||
use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
default::Default,
|
||||||
use core::hash::{Hash, Hasher};
|
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||||
use core::iter::{Product, Sum};
|
hash::{Hash, Hasher},
|
||||||
use core::num::Wrapping as CoreWrapping;
|
iter::{Product, Sum},
|
||||||
use core::ops::{
|
num::Wrapping as CoreWrapping,
|
||||||
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
|
ops::{
|
||||||
Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
|
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.
|
/// Provides intentionally wrapped arithmetic on fixed-point numbers.
|
||||||
|
@ -507,7 +511,7 @@ macro_rules! ops {
|
||||||
I: Iterator<Item = Wrapping<$Fixed<Frac>>>,
|
I: Iterator<Item = Wrapping<$Fixed<Frac>>>,
|
||||||
{
|
{
|
||||||
match iter.next() {
|
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),
|
Some(first) => iter.fold(first, Mul::mul),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,7 +526,7 @@ macro_rules! ops {
|
||||||
I: Iterator<Item = &'a Wrapping<$Fixed<Frac>>>,
|
I: Iterator<Item = &'a Wrapping<$Fixed<Frac>>>,
|
||||||
{
|
{
|
||||||
match iter.next() {
|
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),
|
Some(first) => iter.fold(*first, Mul::mul),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue