1 #[cfg(not(feature = "std"))]
2 use crate::scalar::{Scalar, Value};
5 traits::{ConvertFrom, ConvertTo},
7 use core::{fmt, hash, ops};
13 impl Sealed for F16 {}
14 impl Sealed for f32 {}
15 impl Sealed for f64 {}
17 impl Sealed for u16 {}
18 impl Sealed for u32 {}
19 impl Sealed for u64 {}
21 impl Sealed for i16 {}
22 impl Sealed for i32 {}
23 impl Sealed for i64 {}
35 + ops::Add<Output = Self>
36 + ops::Sub<Output = Self>
37 + ops::Mul<Output = Self>
38 + ops::Div<Output = Self>
39 + ops::Rem<Output = Self>
78 + ops::BitAnd<Output = Self>
79 + ops::BitOr<Output = Self>
80 + ops::BitXor<Output = Self>
81 + ops::Shl<Output = Self>
82 + ops::Shr<Output = Self>
83 + ops::Not<Output = Self>
97 pub trait PrimUInt: PrimInt + ConvertFrom<Self::SignedType> {
98 type SignedType: PrimSInt<UnsignedType = Self> + ConvertFrom<Self>;
101 pub trait PrimSInt: PrimInt + ops::Neg<Output = Self> + ConvertFrom<Self::UnsignedType> {
102 type UnsignedType: PrimUInt<SignedType = Self> + ConvertFrom<Self>;
105 macro_rules! impl_int {
106 ($uint:ident, $sint:ident) => {
107 impl PrimBase for $uint {}
108 impl PrimBase for $sint {}
109 impl PrimInt for $uint {
110 const ZERO: Self = 0;
113 const MAX: Self = !0;
114 const BITS: Self = (0 as $uint).count_zeros() as $uint;
116 impl PrimInt for $sint {
117 const ZERO: Self = 0;
119 const MIN: Self = $sint::MIN;
120 const MAX: Self = $sint::MAX;
121 const BITS: Self = (0 as $sint).count_zeros() as $sint;
123 impl PrimUInt for $uint {
124 type SignedType = $sint;
126 impl PrimSInt for $sint {
127 type UnsignedType = $uint;
139 + ops::Neg<Output = Self>
140 + ConvertFrom<Self::BitsType>
141 + ConvertFrom<Self::SignedBitsType>
145 type BitsType: PrimUInt<SignedType = Self::SignedBitsType> + ConvertFrom<Self>;
146 type SignedBitsType: PrimSInt<UnsignedType = Self::BitsType> + ConvertFrom<Self>;
147 const EXPONENT_BIAS_UNSIGNED: Self::BitsType;
148 const EXPONENT_BIAS_SIGNED: Self::SignedBitsType;
149 const SIGN_FIELD_WIDTH: Self::BitsType;
150 const EXPONENT_FIELD_WIDTH: Self::BitsType;
151 const MANTISSA_FIELD_WIDTH: Self::BitsType;
152 const SIGN_FIELD_SHIFT: Self::BitsType;
153 const EXPONENT_FIELD_SHIFT: Self::BitsType;
154 const MANTISSA_FIELD_SHIFT: Self::BitsType;
155 const SIGN_FIELD_MASK: Self::BitsType;
156 const EXPONENT_FIELD_MASK: Self::BitsType;
157 const MANTISSA_FIELD_MASK: Self::BitsType;
158 const IMPLICIT_MANTISSA_BIT: Self::BitsType;
159 const ZERO_SUBNORMAL_EXPONENT: Self::BitsType;
160 const NAN_INFINITY_EXPONENT: Self::BitsType;
161 const INFINITY_BITS: Self::BitsType;
162 const NAN_BITS: Self::BitsType;
163 fn is_nan(self) -> bool;
164 fn from_bits(bits: Self::BitsType) -> Self;
165 fn to_bits(self) -> Self::BitsType;
166 fn abs(self) -> Self;
167 fn max_contiguous_integer() -> Self {
168 (Self::BitsType::cvt_from(1) << (Self::MANTISSA_FIELD_WIDTH + 1.to())).to()
170 fn is_finite(self) -> bool;
171 fn trunc(self) -> Self;
172 /// round to nearest, ties to unspecified
173 fn round(self) -> Self;
174 fn floor(self) -> Self;
175 fn ceil(self) -> Self;
176 fn copy_sign(self, sign: Self) -> Self;
179 macro_rules! impl_float {
181 impl PrimFloat for $float:ident {
182 type BitsType = $bits_type:ident;
183 type SignedBitsType = $signed_bits_type:ident;
184 const EXPONENT_FIELD_WIDTH: u32 = $exponent_field_width:literal;
185 const MANTISSA_FIELD_WIDTH: u32 = $mantissa_field_width:literal;
188 impl PrimBase for $float {}
190 impl PrimFloat for $float {
191 type BitsType = $bits_type;
192 type SignedBitsType = $signed_bits_type;
193 const EXPONENT_BIAS_UNSIGNED: Self::BitsType =
194 (1 << (Self::EXPONENT_FIELD_WIDTH - 1)) - 1;
195 const EXPONENT_BIAS_SIGNED: Self::SignedBitsType = Self::EXPONENT_BIAS_UNSIGNED as _;
196 const SIGN_FIELD_WIDTH: Self::BitsType = 1;
197 const EXPONENT_FIELD_WIDTH: Self::BitsType = $exponent_field_width;
198 const MANTISSA_FIELD_WIDTH: Self::BitsType = $mantissa_field_width;
199 const SIGN_FIELD_SHIFT: Self::BitsType =
200 Self::EXPONENT_FIELD_SHIFT + Self::EXPONENT_FIELD_WIDTH;
201 const EXPONENT_FIELD_SHIFT: Self::BitsType = Self::MANTISSA_FIELD_WIDTH;
202 const MANTISSA_FIELD_SHIFT: Self::BitsType = 0;
203 const SIGN_FIELD_MASK: Self::BitsType = 1 << Self::SIGN_FIELD_SHIFT;
204 const EXPONENT_FIELD_MASK: Self::BitsType =
205 ((1 << Self::EXPONENT_FIELD_WIDTH) - 1) << Self::EXPONENT_FIELD_SHIFT;
206 const MANTISSA_FIELD_MASK: Self::BitsType = (1 << Self::MANTISSA_FIELD_WIDTH) - 1;
207 const IMPLICIT_MANTISSA_BIT: Self::BitsType = 1 << Self::MANTISSA_FIELD_WIDTH;
208 const ZERO_SUBNORMAL_EXPONENT: Self::BitsType = 0;
209 const NAN_INFINITY_EXPONENT: Self::BitsType = (1 << Self::EXPONENT_FIELD_WIDTH) - 1;
210 const INFINITY_BITS: Self::BitsType =
211 Self::NAN_INFINITY_EXPONENT << Self::EXPONENT_FIELD_SHIFT;
212 const NAN_BITS: Self::BitsType =
213 Self::INFINITY_BITS | (1 << (Self::MANTISSA_FIELD_WIDTH - 1));
214 fn is_nan(self) -> bool {
217 fn from_bits(bits: Self::BitsType) -> Self {
218 $float::from_bits(bits)
220 fn to_bits(self) -> Self::BitsType {
223 fn abs(self) -> Self {
224 #[cfg(feature = "std")]
225 return $float::abs(self);
226 #[cfg(not(feature = "std"))]
227 return crate::algorithms::base::abs(Scalar, Value(self)).0;
229 fn is_finite(self) -> bool {
230 $float::is_finite(self)
232 fn trunc(self) -> Self {
233 #[cfg(feature = "std")]
234 return $float::trunc(self);
235 #[cfg(not(feature = "std"))]
236 return crate::algorithms::base::trunc(Scalar, Value(self)).0;
238 fn round(self) -> Self {
239 #[cfg(feature = "std")]
240 return $float::round(self);
241 #[cfg(not(feature = "std"))]
242 return crate::algorithms::base::round_to_nearest_ties_to_even(Scalar, Value(self))
245 fn floor(self) -> Self {
246 #[cfg(feature = "std")]
247 return $float::floor(self);
248 #[cfg(not(feature = "std"))]
249 return crate::algorithms::base::floor(Scalar, Value(self)).0;
251 fn ceil(self) -> Self {
252 #[cfg(feature = "std")]
253 return $float::ceil(self);
254 #[cfg(not(feature = "std"))]
255 return crate::algorithms::base::ceil(Scalar, Value(self)).0;
257 fn copy_sign(self, sign: Self) -> Self {
258 #[cfg(feature = "std")]
259 return $float::copysign(self, sign);
260 #[cfg(not(feature = "std"))]
261 return crate::algorithms::base::copy_sign(Scalar, Value(self), Value(sign)).0;
268 impl PrimFloat for F16 {
270 type SignedBitsType = i16;
271 const EXPONENT_FIELD_WIDTH: u32 = 5;
272 const MANTISSA_FIELD_WIDTH: u32 = 10;
277 impl PrimFloat for f32 {
279 type SignedBitsType = i32;
280 const EXPONENT_FIELD_WIDTH: u32 = 8;
281 const MANTISSA_FIELD_WIDTH: u32 = 23;
286 impl PrimFloat for f64 {
288 type SignedBitsType = i64;
289 const EXPONENT_FIELD_WIDTH: u32 = 11;
290 const MANTISSA_FIELD_WIDTH: u32 = 52;