substrate_fixed/wrapping.rs
1// Copyright © 2018–2019 Trevor Spiteri
2
3// This library is free software: you can redistribute it and/or
4// modify it under the terms of either
5//
6// * the Apache License, Version 2.0 or
7// * the MIT License
8//
9// at your option.
10//
11// You should have recieved copies of the Apache License and the MIT
12// License along with the library. If not, see
13// <https://www.apache.org/licenses/LICENSE-2.0> and
14// <https://opensource.org/licenses/MIT>.
15
16#![allow(clippy::suspicious_op_assign_impl)]
17
18use crate::{
19 from_str::ParseFixedError,
20 traits::{Fixed, FixedSigned, FixedUnsigned, FromFixed, ToFixed},
21 types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8},
22 FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
23 FixedU8,
24};
25use core::{
26 fmt::{Display, Formatter, Result as FmtResult},
27 iter::{Product, Sum},
28 mem,
29 ops::{
30 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
31 DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
32 SubAssign,
33 },
34 str::FromStr,
35};
36
37/// Provides intentionally wrapped arithmetic on fixed-point numbers.
38///
39/// The underlying value can be retrieved through the `.0` index.
40///
41/// # Examples
42///
43/// ```rust
44/// use substrate_fixed::{types::I16F16, Wrapping};
45/// let max = Wrapping(I16F16::max_value());
46/// let delta = Wrapping(I16F16::from_bits(1));
47/// assert_eq!(I16F16::min_value(), (max + delta).0);
48/// ```
49#[repr(transparent)]
50#[derive(Clone, Copy, Default, Hash, Debug, Eq, PartialEq, Ord, PartialOrd, scale_info::TypeInfo)]
51pub struct Wrapping<F>(pub F);
52
53impl<F: Fixed> Wrapping<F> {
54 /// Returns the smallest value that can be represented.
55 ///
56 /// # Examples
57 ///
58 /// ```rust
59 /// use substrate_fixed::{types::I16F16, Wrapping};
60 /// assert_eq!(Wrapping::<I16F16>::min_value(), Wrapping(I16F16::min_value()));
61 /// ```
62 #[inline]
63 pub fn min_value() -> Wrapping<F> {
64 Wrapping(F::min_value())
65 }
66
67 /// Returns the largest value that can be represented.
68 ///
69 /// # Examples
70 ///
71 /// ```rust
72 /// use substrate_fixed::{types::I16F16, Wrapping};
73 /// assert_eq!(Wrapping::<I16F16>::max_value(), Wrapping(I16F16::max_value()));
74 /// ```
75 #[inline]
76 pub fn max_value() -> Wrapping<F> {
77 Wrapping(F::max_value())
78 }
79
80 /// Returns the number of integer bits.
81 ///
82 /// # Examples
83 ///
84 /// ```rust
85 /// use substrate_fixed::{types::I16F16, Wrapping};
86 /// assert_eq!(Wrapping::<I16F16>::int_nbits(), I16F16::int_nbits());
87 /// ```
88 #[inline]
89 pub fn int_nbits() -> u32 {
90 F::int_nbits()
91 }
92
93 /// Returns the number of fractional bits.
94 ///
95 /// # Examples
96 ///
97 /// ```rust
98 /// use substrate_fixed::{types::I16F16, Wrapping};
99 /// assert_eq!(Wrapping::<I16F16>::frac_nbits(), I16F16::frac_nbits());
100 /// ```
101 #[inline]
102 pub fn frac_nbits() -> u32 {
103 F::frac_nbits()
104 }
105
106 /// Creates a fixed-point number that has a bitwise representation
107 /// identical to the given integer.
108 ///
109 /// # Examples
110 ///
111 /// ```rust
112 /// use substrate_fixed::{types::I16F16, Wrapping};
113 /// assert_eq!(Wrapping::<I16F16>::from_bits(0x1C), Wrapping(I16F16::from_bits(0x1C)));
114 /// ```
115 #[inline]
116 pub fn from_bits(bits: F::Bits) -> Wrapping<F> {
117 Wrapping(F::from_bits(bits))
118 }
119
120 /// Creates an integer that has a bitwise representation identical
121 /// to the given fixed-point number.
122 ///
123 /// # Examples
124 ///
125 /// ```rust
126 /// use substrate_fixed::{types::I16F16, Wrapping};
127 /// let w = Wrapping(I16F16::from_bits(0x1C));
128 /// assert_eq!(w.to_bits(), 0x1C);
129 /// ```
130 #[inline]
131 pub fn to_bits(self) -> F::Bits {
132 self.0.to_bits()
133 }
134
135 /// Wrapping conversion from another number.
136 ///
137 /// The other number can be:
138 ///
139 /// * A fixed-point number. Any extra fractional bits are truncated.
140 /// * An integer of type [`i8`], [`i16`], [`i32`], [`i64`], [`i128`],
141 /// [`isize`], [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], or
142 /// [`usize`].
143 /// * A floating-point number of type [`f32`] or [`f64`]. If the
144 /// [`f16` feature] is enabled, it can also be of type [`f16`]
145 /// or [`bf16`]. For this conversion, the method rounds to the
146 /// nearest, with ties rounding to even.
147 /// * Any other number `src` for which [`ToFixed`] is implemented, in
148 /// which case this method returns
149 /// <code>[Wrapping][`Wrapping`]([src.wrapping_to_fixed()][`wrapping_to_fixed`])</code>.
150 ///
151 /// # Panics
152 ///
153 /// For floating-point numbers, panics if the value is not [finite].
154 ///
155 /// # Examples
156 ///
157 /// ```rust
158 /// use substrate_fixed::{
159 /// types::{I4F4, I16F16},
160 /// Wrapping,
161 /// };
162 ///
163 /// // 0x1234.5678 wraps into 0x4.5
164 /// let src = I16F16::from_bits(0x1234_5678);
165 /// let dst = Wrapping::<I4F4>::from_num(src);
166 /// assert_eq!(dst, Wrapping(I4F4::from_bits(0x45)));
167 ///
168 /// // 0x1234 wraps into 0x4.0
169 /// let src_int = 0x1234_i32;
170 /// let dst_int = Wrapping::<I4F4>::from_num(src_int);
171 /// assert_eq!(dst_int, Wrapping(I4F4::from_bits(0x40)));
172 ///
173 /// // 129.75 wrapped into 1.75 (binary 1.1100)
174 /// let src_float = 129.75;
175 /// let dst_float = Wrapping::<I4F4>::from_num(src_float);
176 /// assert_eq!(dst_float, Wrapping(I4F4::from_bits(0b11100)));
177 /// ```
178 ///
179 /// [`ToFixed`]: traits/trait.ToFixed.html
180 /// [`Wrapping`]: struct.Wrapping.html
181 /// [`bf16`]: https://docs.rs/half/^1.2/half/struct.bf16.html
182 /// [`f16` feature]: index.html#optional-features
183 /// [`f16`]: https://docs.rs/half/^1.2/half/struct.f16.html
184 /// [`f32`]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
185 /// [`f64`]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
186 /// [`i128`]: https://doc.rust-lang.org/nightly/std/primitive.i128.html
187 /// [`i16`]: https://doc.rust-lang.org/nightly/std/primitive.i16.html
188 /// [`i32`]: https://doc.rust-lang.org/nightly/std/primitive.i32.html
189 /// [`i64`]: https://doc.rust-lang.org/nightly/std/primitive.i64.html
190 /// [`i8`]: https://doc.rust-lang.org/nightly/std/primitive.i8.html
191 /// [`isize`]: https://doc.rust-lang.org/nightly/std/primitive.isize.html
192 /// [`wrapping_to_fixed`]: traits/trait.ToFixed.html#tymethod.wrapping_to_fixed
193 /// [`u128`]: https://doc.rust-lang.org/nightly/std/primitive.u128.html
194 /// [`u16`]: https://doc.rust-lang.org/nightly/std/primitive.u16.html
195 /// [`u32`]: https://doc.rust-lang.org/nightly/std/primitive.u32.html
196 /// [`u64`]: https://doc.rust-lang.org/nightly/std/primitive.u64.html
197 /// [`u8`]: https://doc.rust-lang.org/nightly/std/primitive.u8.html
198 /// [`usize`]: https://doc.rust-lang.org/nightly/std/primitive.usize.html
199 /// [finite]: https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.is_finite
200 #[inline]
201 pub fn from_num<Src: ToFixed>(src: Src) -> Wrapping<F> {
202 Wrapping(src.wrapping_to_fixed())
203 }
204
205 /// Converts a fixed-point number to another number, wrapping the
206 /// value on overflow.
207 ///
208 /// The other number can be:
209 ///
210 /// * Another fixed-point number. Any extra fractional bits are truncated.
211 /// * An integer of type [`i8`], [`i16`], [`i32`], [`i64`], [`i128`],
212 /// [`isize`], [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], or
213 /// [`usize`]. Any fractional bits are truncated.
214 /// * A floating-point number of type [`f32`] or [`f64`]. If the
215 /// [`f16` feature] is enabled, it can also be of type [`f16`]
216 /// or [`bf16`]. For this conversion, the method rounds to the
217 /// nearest, with ties rounding to even.
218 /// * Any other type `Dst` for which [`FromFixed`] is implemented, in
219 /// which case this method returns
220 /// [`Dst::wrapping_from_fixed(self.0)`][`wrapping_from_fixed`].
221 ///
222 /// # Examples
223 ///
224 /// ```rust
225 /// use substrate_fixed::{
226 /// types::{I16F16, I2F6, I4F4},
227 /// Wrapping,
228 /// };
229 ///
230 /// // conversion that fits
231 /// let src = Wrapping(I4F4::from_num(1.75));
232 /// let expected = I16F16::from_num(1.75);
233 /// assert_eq!(src.to_num::<I16F16>(), expected);
234 ///
235 /// // conversion that wraps
236 /// let src = Wrapping(I4F4::max_value());
237 /// let wrapped = I2F6::from_bits(I2F6::max_value().to_bits() << 2);
238 /// assert_eq!(src.to_num::<I2F6>(), wrapped);
239 /// ```
240 ///
241 /// [`FromFixed`]: traits/trait.FromFixed.html
242 /// [`bf16`]: https://docs.rs/half/^1.2/half/struct.bf16.html
243 /// [`f16` feature]: index.html#optional-features
244 /// [`f16`]: https://docs.rs/half/^1.2/half/struct.f16.html
245 /// [`f32`]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
246 /// [`f64`]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
247 /// [`wrapping_from_fixed`]: traits/trait.FromFixed.html#tymethod.wrapping_from_fixed
248 /// [`i128`]: https://doc.rust-lang.org/nightly/std/primitive.i128.html
249 /// [`i16`]: https://doc.rust-lang.org/nightly/std/primitive.i16.html
250 /// [`i32`]: https://doc.rust-lang.org/nightly/std/primitive.i32.html
251 /// [`i64`]: https://doc.rust-lang.org/nightly/std/primitive.i64.html
252 /// [`i8`]: https://doc.rust-lang.org/nightly/std/primitive.i8.html
253 /// [`isize`]: https://doc.rust-lang.org/nightly/std/primitive.isize.html
254 /// [`u128`]: https://doc.rust-lang.org/nightly/std/primitive.u128.html
255 /// [`u16`]: https://doc.rust-lang.org/nightly/std/primitive.u16.html
256 /// [`u32`]: https://doc.rust-lang.org/nightly/std/primitive.u32.html
257 /// [`u64`]: https://doc.rust-lang.org/nightly/std/primitive.u64.html
258 /// [`u8`]: https://doc.rust-lang.org/nightly/std/primitive.u8.html
259 /// [`usize`]: https://doc.rust-lang.org/nightly/std/primitive.usize.html
260 #[inline]
261 pub fn to_num<Dst: FromFixed>(self) -> Dst {
262 Dst::wrapping_from_fixed(self.0)
263 }
264
265 /// Parses a string slice containing binary digits to return a fixed-point number.
266 ///
267 /// Rounding is to the nearest, with ties rounded to even.
268 ///
269 /// # Examples
270 ///
271 /// ```rust
272 /// use substrate_fixed::{types::I8F8, Wrapping};
273 /// let check = Wrapping(I8F8::from_bits(0b1110001 << (8 - 1)));
274 /// assert_eq!(Wrapping::<I8F8>::from_str_binary("101100111000.1"), Ok(check));
275 /// ```
276 #[inline]
277 pub fn from_str_binary(src: &str) -> Result<Wrapping<F>, ParseFixedError> {
278 F::wrapping_from_str_binary(src).map(Wrapping)
279 }
280
281 /// Parses a string slice containing octal digits to return a fixed-point number.
282 ///
283 /// Rounding is to the nearest, with ties rounded to even.
284 ///
285 /// # Examples
286 ///
287 /// ```rust
288 /// use substrate_fixed::{types::I8F8, Wrapping};
289 /// let check = Wrapping(I8F8::from_bits(0o1654 << (8 - 3)));
290 /// assert_eq!(Wrapping::<I8F8>::from_str_octal("7165.4"), Ok(check));
291 /// ```
292 #[inline]
293 pub fn from_str_octal(src: &str) -> Result<Wrapping<F>, ParseFixedError> {
294 F::wrapping_from_str_octal(src).map(Wrapping)
295 }
296
297 /// Parses a string slice containing hexadecimal digits to return a fixed-point number.
298 ///
299 /// Rounding is to the nearest, with ties rounded to even.
300 ///
301 /// # Examples
302 ///
303 /// ```rust
304 /// use substrate_fixed::{types::I8F8, Wrapping};
305 /// let check = Wrapping(I8F8::from_bits(0xFFE));
306 /// assert_eq!(Wrapping::<I8F8>::from_str_hex("C0F.FE"), Ok(check));
307 /// ```
308 #[inline]
309 pub fn from_str_hex(src: &str) -> Result<Wrapping<F>, ParseFixedError> {
310 F::wrapping_from_str_hex(src).map(Wrapping)
311 }
312
313 /// Returns the integer part.
314 ///
315 /// Note that since the numbers are stored in two’s complement,
316 /// negative numbers with non-zero fractional parts will be
317 /// rounded towards −∞, except in the case where there are no
318 /// integer bits, for example for the type
319 /// <code>[Wrapping][`Wrapping`]<[I0F16][`I0F16`]></code>,
320 /// where the return value is always zero.
321 ///
322 /// # Examples
323 ///
324 /// ```rust
325 /// use substrate_fixed::{types::I16F16, Wrapping};
326 /// assert_eq!(Wrapping(I16F16::from_num(12.25)).int(), Wrapping(I16F16::from_num(12)));
327 /// assert_eq!(Wrapping(I16F16::from_num(-12.25)).int(), Wrapping(I16F16::from_num(-13)));
328 /// ```
329 ///
330 /// [`I0F16`]: types/type.I0F16.html
331 /// [`Wrapping`]: struct.Wrapping.html
332 #[inline]
333 pub fn int(self) -> Wrapping<F> {
334 Wrapping(self.0.int())
335 }
336
337 /// Returns the fractional part.
338 ///
339 /// Note that since the numbers are stored in two’s complement,
340 /// the returned fraction will be non-negative for negative
341 /// numbers, except in the case where there are no integer bits,
342 /// for example for the type
343 /// <code>[Wrapping][`Wrapping`]<[I0F16][`I0F16`]></code>,
344 /// where the return value is always equal to `self`.
345 ///
346 /// # Examples
347 ///
348 /// ```rust
349 /// use substrate_fixed::{types::I16F16, Wrapping};
350 /// assert_eq!(Wrapping(I16F16::from_num(12.25)).frac(), Wrapping(I16F16::from_num(0.25)));
351 /// assert_eq!(Wrapping(I16F16::from_num(-12.25)).frac(), Wrapping(I16F16::from_num(0.75)));
352 /// ```
353 ///
354 /// [`I0F16`]: types/type.I0F16.html
355 /// [`Wrapping`]: struct.Wrapping.html
356 #[inline]
357 pub fn frac(self) -> Wrapping<F> {
358 Wrapping(self.0.frac())
359 }
360
361 /// Rounds to the next integer towards 0.
362 ///
363 /// # Examples
364 ///
365 /// ```rust
366 /// use substrate_fixed::{types::I16F16, Wrapping};
367 /// let three = Wrapping(I16F16::from_num(3));
368 /// assert_eq!(Wrapping(I16F16::from_num(3.9)).round_to_zero(), three);
369 /// assert_eq!(Wrapping(I16F16::from_num(-3.9)).round_to_zero(), -three);
370 /// ```
371 #[inline]
372 pub fn round_to_zero(self) -> Wrapping<F> {
373 Wrapping(self.0.round_to_zero())
374 }
375
376 /// Wrapping ceil. Rounds to the next integer towards +∞, wrapping
377 /// on overflow.
378 ///
379 /// # Examples
380 ///
381 /// ```rust
382 /// use substrate_fixed::{types::I16F16, Wrapping};
383 /// let two_half = Wrapping(I16F16::from_num(5) / 2);
384 /// assert_eq!(two_half.ceil(), Wrapping(I16F16::from_num(3)));
385 /// assert_eq!(Wrapping(I16F16::max_value()).ceil(), Wrapping(I16F16::min_value()));
386 /// ```
387 #[inline]
388 pub fn ceil(self) -> Wrapping<F> {
389 Wrapping(self.0.wrapping_ceil())
390 }
391
392 /// Wrapping floor. Rounds to the next integer towards −∞,
393 /// wrapping on overflow.
394 ///
395 /// Overflow can only occur for signed numbers with zero integer
396 /// bits.
397 ///
398 /// # Examples
399 ///
400 /// ```rust
401 /// use substrate_fixed::{
402 /// types::{I0F32, I16F16},
403 /// Wrapping,
404 /// };
405 /// let two_half = Wrapping(I16F16::from_num(5) / 2);
406 /// assert_eq!(two_half.floor(), Wrapping(I16F16::from_num(2)));
407 /// assert_eq!(Wrapping(I0F32::min_value()).floor(), Wrapping(I0F32::from_num(0)));
408 /// ```
409 #[inline]
410 pub fn floor(self) -> Wrapping<F> {
411 Wrapping(self.0.wrapping_floor())
412 }
413
414 /// Wrapping round. Rounds to the next integer to the nearest,
415 /// with ties rounded away from zero, and wrapping on overflow.
416 ///
417 /// # Examples
418 ///
419 /// ```rust
420 /// use substrate_fixed::{types::I16F16, Wrapping};
421 /// let two_half = Wrapping(I16F16::from_num(5) / 2);
422 /// assert_eq!(two_half.round(), Wrapping(I16F16::from_num(3)));
423 /// assert_eq!((-two_half).round(), Wrapping(I16F16::from_num(-3)));
424 /// assert_eq!(Wrapping(I16F16::max_value()).round(), Wrapping(I16F16::min_value()));
425 /// ```
426 #[inline]
427 pub fn round(self) -> Wrapping<F> {
428 Wrapping(self.0.wrapping_round())
429 }
430
431 /// Wrapping round. Rounds to the next integer to the nearest,
432 /// with ties rounded to even, and wrapping on overflow.
433 ///
434 /// # Examples
435 ///
436 /// ```rust
437 /// use substrate_fixed::{types::I16F16, Wrapping};
438 /// let two_half = Wrapping(I16F16::from_num(2.5));
439 /// assert_eq!(two_half.round_ties_to_even(), Wrapping(I16F16::from_num(2)));
440 /// let three_half = Wrapping(I16F16::from_num(3.5));
441 /// assert_eq!(three_half.round_ties_to_even(), Wrapping(I16F16::from_num(4)));
442 /// let max = Wrapping(I16F16::max_value());
443 /// assert_eq!(max.round_ties_to_even(), Wrapping(I16F16::min_value()));
444 /// ```
445 #[inline]
446 pub fn round_ties_to_even(self) -> Wrapping<F> {
447 Wrapping(self.0.wrapping_round_ties_to_even())
448 }
449
450 /// Returns the number of ones in the binary representation.
451 ///
452 /// # Examples
453 ///
454 /// ```rust
455 /// use substrate_fixed::{types::I16F16, Wrapping};
456 /// let w = Wrapping(I16F16::from_bits(0x00FF_FF00));
457 /// assert_eq!(w.count_ones(), w.0.count_ones());
458 /// ```
459 #[inline]
460 pub fn count_ones(self) -> u32 {
461 self.0.count_ones()
462 }
463
464 /// Returns the number of zeros in the binary representation.
465 ///
466 /// # Examples
467 ///
468 /// ```rust
469 /// use substrate_fixed::{types::I16F16, Wrapping};
470 /// let w = Wrapping(I16F16::from_bits(0x00FF_FF00));
471 /// assert_eq!(w.count_zeros(), w.0.count_zeros());
472 /// ```
473 #[inline]
474 pub fn count_zeros(self) -> u32 {
475 self.0.count_zeros()
476 }
477
478 /// Returns the number of leading zeros in the binary representation.
479 ///
480 /// # Examples
481 ///
482 /// ```rust
483 /// use substrate_fixed::{types::I16F16, Wrapping};
484 /// let w = Wrapping(I16F16::from_bits(0x00FF_FF00));
485 /// assert_eq!(w.leading_zeros(), w.0.leading_zeros());
486 /// ```
487 #[inline]
488 pub fn leading_zeros(self) -> u32 {
489 self.0.leading_zeros()
490 }
491
492 /// Returns the number of trailing zeros in the binary representation.
493 ///
494 /// # Examples
495 ///
496 /// ```rust
497 /// use substrate_fixed::{types::I16F16, Wrapping};
498 /// let w = Wrapping(I16F16::from_bits(0x00FF_FF00));
499 /// assert_eq!(w.trailing_zeros(), w.0.trailing_zeros());
500 /// ```
501 #[inline]
502 pub fn trailing_zeros(self) -> u32 {
503 self.0.trailing_zeros()
504 }
505
506 /// Shifts to the left by `n` bits, wrapping the truncated bits to the right end.
507 ///
508 /// # Examples
509 ///
510 /// ```rust
511 /// use substrate_fixed::{types::I16F16, Wrapping};
512 /// let i = I16F16::from_bits(0x00FF_FF00);
513 /// assert_eq!(Wrapping(i).rotate_left(12), Wrapping(i.rotate_left(12)));
514 /// ```
515 #[inline]
516 pub fn rotate_left(self, n: u32) -> Wrapping<F> {
517 Wrapping(self.0.rotate_left(n))
518 }
519
520 /// Shifts to the right by `n` bits, wrapping the truncated bits to the left end.
521 ///
522 /// # Examples
523 ///
524 /// ```rust
525 /// use substrate_fixed::{types::I16F16, Wrapping};
526 /// let i = I16F16::from_bits(0x00FF_FF00);
527 /// assert_eq!(Wrapping(i).rotate_right(12), Wrapping(i.rotate_right(12)));
528 /// ```
529 #[inline]
530 pub fn rotate_right(self, n: u32) -> Wrapping<F> {
531 Wrapping(self.0.rotate_right(n))
532 }
533
534 /// Euclidean division.
535 ///
536 /// # Panics
537 ///
538 /// Panics if the divisor is zero.
539 ///
540 /// # Examples
541 ///
542 /// ```rust
543 /// use substrate_fixed::{types::I16F16, Wrapping};
544 /// let num = Wrapping(I16F16::from_num(7.5));
545 /// let den = Wrapping(I16F16::from_num(2));
546 /// assert_eq!(num.div_euclid(den), Wrapping(I16F16::from_num(3)));
547 /// let quarter = Wrapping(I16F16::from_num(0.25));
548 /// let check = (Wrapping::max_value() * 4i32).round_to_zero();
549 /// assert_eq!(Wrapping::max_value().div_euclid(quarter), check);
550 /// ```
551 #[inline]
552 pub fn div_euclid(self, divisor: Wrapping<F>) -> Wrapping<F> {
553 Wrapping(self.0.wrapping_div_euclid(divisor.0))
554 }
555
556 /// Remainder for Euclidean division.
557 ///
558 /// # Panics
559 ///
560 /// Panics if the divisor is zero.
561 ///
562 /// # Examples
563 ///
564 /// ```rust
565 /// use substrate_fixed::{types::I16F16, Wrapping};
566 /// let num = Wrapping(I16F16::from_num(7.5));
567 /// let den = Wrapping(I16F16::from_num(2));
568 /// assert_eq!(num.rem_euclid(den), Wrapping(I16F16::from_num(1.5)));
569 /// assert_eq!((-num).rem_euclid(den), Wrapping(I16F16::from_num(0.5)));
570 /// ```
571 #[inline]
572 pub fn rem_euclid(self, divisor: Wrapping<F>) -> Wrapping<F> {
573 Wrapping(self.0.rem_euclid(divisor.0))
574 }
575
576 /// Euclidean division by an integer.
577 ///
578 /// # Panics
579 ///
580 /// Panics if the divisor is zero.
581 ///
582 /// # Examples
583 ///
584 /// ```rust
585 /// use substrate_fixed::{types::I16F16, Wrapping};
586 /// let num = Wrapping(I16F16::from_num(7.5));
587 /// assert_eq!(num.div_euclid_int(2), Wrapping(I16F16::from_num(3)));
588 /// let min = Wrapping(I16F16::min_value());
589 /// assert_eq!(min.div_euclid_int(-1), min);
590 /// ```
591 #[inline]
592 pub fn div_euclid_int(self, divisor: F::Bits) -> Wrapping<F> {
593 Wrapping(self.0.wrapping_div_euclid_int(divisor))
594 }
595
596 /// Remainder for Euclidean division.
597 ///
598 /// # Panics
599 ///
600 /// Panics if the divisor is zero.
601 ///
602 /// # Examples
603 ///
604 /// ```rust
605 /// use substrate_fixed::{types::I16F16, Wrapping};
606 /// let num = Wrapping(I16F16::from_num(7.5));
607 /// assert_eq!(num.rem_euclid_int(2), Wrapping(I16F16::from_num(1.5)));
608 /// assert_eq!((-num).rem_euclid_int(2), Wrapping(I16F16::from_num(0.5)));
609 /// ```
610 #[inline]
611 pub fn rem_euclid_int(self, divisor: F::Bits) -> Wrapping<F> {
612 Wrapping(self.0.wrapping_rem_euclid_int(divisor))
613 }
614}
615
616impl<F: FixedSigned> Wrapping<F> {
617 /// Returns [`true`][`bool`] if the number is > 0.
618 ///
619 /// # Examples
620 ///
621 /// ```rust
622 /// use substrate_fixed::{types::I16F16, Wrapping};
623 /// assert!(Wrapping(I16F16::from_num(4.3)).is_positive());
624 /// assert!(!Wrapping(I16F16::from_num(0)).is_positive());
625 /// assert!(!Wrapping(I16F16::from_num(-4.3)).is_positive());
626 /// ```
627 ///
628 /// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
629 #[inline]
630 pub fn is_positive(self) -> bool {
631 self.0.is_positive()
632 }
633
634 /// Returns [`true`][`bool`] if the number is < 0.
635 ///
636 /// # Examples
637 ///
638 /// ```rust
639 /// use substrate_fixed::{types::I16F16, Wrapping};
640 /// assert!(!Wrapping(I16F16::from_num(4.3)).is_negative());
641 /// assert!(!Wrapping(I16F16::from_num(0)).is_negative());
642 /// assert!(Wrapping(I16F16::from_num(-4.3)).is_negative());
643 /// ```
644 ///
645 /// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
646 #[inline]
647 pub fn is_negative(self) -> bool {
648 self.0.is_negative()
649 }
650
651 /// Wrapping absolute value. Returns the absolute value, wrapping
652 /// on overflow.
653 ///
654 /// Overflow can only occur when trying to find the absolute value
655 /// of the minimum value.
656 ///
657 /// # Examples
658 ///
659 /// ```rust
660 /// use substrate_fixed::{types::I16F16, Wrapping};
661 /// assert_eq!(Wrapping(I16F16::from_num(-5)).abs(), Wrapping(I16F16::from_num(5)));
662 /// assert_eq!(Wrapping(I16F16::min_value()).abs(), Wrapping(I16F16::min_value()));
663 /// ```
664 #[inline]
665 pub fn abs(self) -> Wrapping<F> {
666 Wrapping(self.0.wrapping_abs())
667 }
668
669 /// Returns a number representing the sign of `self`.
670 ///
671 /// # Warning
672 ///
673 /// Using this method when 1 and −1 cannot be represented is
674 /// almost certainly a bug, however, this is allowed and gives the
675 /// following wrapped results.
676 ///
677 /// * When there are no integer bits, for example for the type
678 /// <code>[Wrapping][`Wrapping`]<[I0F16][`I0F16`]></code>,
679 /// the return value is always zero.
680 /// * When there is one integer bit, for example for the type
681 /// <code>[Wrapping][`Wrapping`]<[I1F15][`I1F15`]></code>,
682 /// the return value is zero when `self` is zero, and −1
683 /// otherwise. This means that for a positive number, −1 is
684 /// returned, because +1 does not fit and is wrapped to −1.
685 ///
686 /// # Examples
687 ///
688 /// ```rust
689 /// use substrate_fixed::{types::I16F16, Wrapping};
690 /// assert_eq!(Wrapping(<I16F16>::from_num(-3.9)).signum(), Wrapping(I16F16::from_num(-1)));
691 /// assert_eq!(Wrapping(<I16F16>::from_num(0)).signum(), Wrapping(I16F16::from_num(0)));
692 /// assert_eq!(Wrapping(<I16F16>::from_num(3.9)).signum(), Wrapping(I16F16::from_num(1)));
693 /// ```
694 ///
695 /// [`I0F16`]: types/type.I0F16.html
696 /// [`I1F15`]: types/type.I1F15.html
697 /// [`Wrapping`]: struct.Wrapping.html
698 #[inline]
699 pub fn signum(self) -> Wrapping<F> {
700 if self.is_positive() {
701 Self::from_num(1)
702 } else if self.is_negative() {
703 Self::from_num(-1)
704 } else {
705 Self::from_num(0)
706 }
707 }
708}
709
710impl<F: FixedUnsigned> Wrapping<F> {
711 /// Returns [`true`][`bool`] if the fixed-point number is
712 /// 2<sup><i>k</i></sup> for some integer <i>k</i>.
713 ///
714 /// # Examples
715 ///
716 /// ```rust
717 /// use substrate_fixed::{types::U16F16, Wrapping};
718 /// assert!(Wrapping(U16F16::from_num(0.5)).is_power_of_two());
719 /// assert!(Wrapping(U16F16::from_num(4)).is_power_of_two());
720 /// assert!(!Wrapping(U16F16::from_num(5)).is_power_of_two());
721 /// ```
722 ///
723 /// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
724 #[inline]
725 pub fn is_power_of_two(self) -> bool {
726 self.0.is_power_of_two()
727 }
728
729 /// Returns the smallest power of two that is ≥ `self`.
730 ///
731 /// If the next power of two is too large to fit, it is wrapped to zero.
732 ///
733 /// # Examples
734 ///
735 /// ```rust
736 /// use substrate_fixed::{types::U16F16, Wrapping};
737 /// let half = Wrapping(U16F16::from_num(0.5));
738 /// assert_eq!(Wrapping(U16F16::from_num(0.3)).next_power_of_two(), half);
739 /// let four = Wrapping(U16F16::from_num(4));
740 /// assert_eq!(Wrapping(U16F16::from_num(4)).next_power_of_two(), four);
741 /// let zero = Wrapping(U16F16::from_num(0));
742 /// assert_eq!(Wrapping(U16F16::max_value()).next_power_of_two(), zero);
743 /// ```
744 #[inline]
745 pub fn next_power_of_two(self) -> Wrapping<F> {
746 Wrapping(self.0.checked_next_power_of_two().unwrap_or_default())
747 }
748}
749
750impl<F: Fixed> Display for Wrapping<F> {
751 #[inline]
752 fn fmt(&self, f: &mut Formatter) -> FmtResult {
753 Display::fmt(&self.0, f)
754 }
755}
756
757impl<F: Fixed> From<F> for Wrapping<F> {
758 /// Wraps a fixed-point number.
759 #[inline]
760 fn from(src: F) -> Wrapping<F> {
761 Wrapping(src)
762 }
763}
764
765impl<F: Fixed> FromStr for Wrapping<F> {
766 type Err = ParseFixedError;
767 /// Parses a string slice containing decimal digits to return a fixed-point number.
768 ///
769 /// Rounding is to the nearest, with ties rounded to even.
770 #[inline]
771 fn from_str(s: &str) -> Result<Self, Self::Err> {
772 F::wrapping_from_str(s).map(Wrapping)
773 }
774}
775
776macro_rules! op {
777 ($wrapping:ident, $Op:ident $op:ident, $OpAssign:ident $op_assign:ident) => {
778 impl<F: Fixed> $Op<Wrapping<F>> for Wrapping<F> {
779 type Output = Wrapping<F>;
780 #[inline]
781 fn $op(self, other: Wrapping<F>) -> Wrapping<F> {
782 Wrapping((self.0).$wrapping(other.0))
783 }
784 }
785 impl<'a, F: Fixed> $Op<Wrapping<F>> for &'a Wrapping<F> {
786 type Output = Wrapping<F>;
787 #[inline]
788 fn $op(self, other: Wrapping<F>) -> Wrapping<F> {
789 Wrapping((self.0).$wrapping(other.0))
790 }
791 }
792 impl<'a, F: Fixed> $Op<&'a Wrapping<F>> for Wrapping<F> {
793 type Output = Wrapping<F>;
794 #[inline]
795 fn $op(self, other: &Wrapping<F>) -> Wrapping<F> {
796 Wrapping((self.0).$wrapping(other.0))
797 }
798 }
799 impl<'a, 'b, F: Fixed> $Op<&'a Wrapping<F>> for &'b Wrapping<F> {
800 type Output = Wrapping<F>;
801 #[inline]
802 fn $op(self, other: &Wrapping<F>) -> Wrapping<F> {
803 Wrapping((self.0).$wrapping(other.0))
804 }
805 }
806 impl<F: Fixed> $OpAssign<Wrapping<F>> for Wrapping<F> {
807 #[inline]
808 fn $op_assign(&mut self, other: Wrapping<F>) {
809 self.0 = (self.0).$wrapping(other.0);
810 }
811 }
812 impl<'a, F: Fixed> $OpAssign<&'a Wrapping<F>> for Wrapping<F> {
813 #[inline]
814 fn $op_assign(&mut self, other: &Wrapping<F>) {
815 self.0 = (self.0).$wrapping(other.0);
816 }
817 }
818 };
819}
820
821macro_rules! op_bitwise {
822 ($Op:ident $op:ident, $OpAssign:ident $op_assign:ident) => {
823 impl<F> $Op<Wrapping<F>> for Wrapping<F>
824 where
825 F: $Op<F, Output = F>,
826 {
827 type Output = Wrapping<F>;
828 #[inline]
829 fn $op(self, other: Wrapping<F>) -> Wrapping<F> {
830 Wrapping((self.0).$op(other.0))
831 }
832 }
833 impl<'a, F> $Op<Wrapping<F>> for &'a Wrapping<F>
834 where
835 &'a F: $Op<F, Output = F>,
836 {
837 type Output = Wrapping<F>;
838 #[inline]
839 fn $op(self, other: Wrapping<F>) -> Wrapping<F> {
840 Wrapping((self.0).$op(other.0))
841 }
842 }
843 impl<'a, F> $Op<&'a Wrapping<F>> for Wrapping<F>
844 where
845 F: $Op<&'a F, Output = F>,
846 {
847 type Output = Wrapping<F>;
848 #[inline]
849 fn $op(self, other: &'a Wrapping<F>) -> Wrapping<F> {
850 Wrapping((self.0).$op(&other.0))
851 }
852 }
853 impl<'a, 'b, F> $Op<&'a Wrapping<F>> for &'b Wrapping<F>
854 where
855 &'b F: $Op<&'a F, Output = F>,
856 {
857 type Output = Wrapping<F>;
858 #[inline]
859 fn $op(self, other: &'a Wrapping<F>) -> Wrapping<F> {
860 Wrapping((self.0).$op(&other.0))
861 }
862 }
863 impl<F> $OpAssign<Wrapping<F>> for Wrapping<F>
864 where
865 F: $OpAssign<F>,
866 {
867 #[inline]
868 fn $op_assign(&mut self, other: Wrapping<F>) {
869 (self.0).$op_assign(other.0);
870 }
871 }
872 impl<'a, F> $OpAssign<&'a Wrapping<F>> for Wrapping<F>
873 where
874 F: $OpAssign<&'a F>,
875 {
876 #[inline]
877 fn $op_assign(&mut self, other: &'a Wrapping<F>) {
878 (self.0).$op_assign(&other.0);
879 }
880 }
881 };
882}
883
884macro_rules! op_shift {
885 (
886 $Op:ident $op:ident, $OpAssign:ident $op_assign:ident;
887 $($Rhs:ident),*
888 ) => { $(
889 impl<F> $Op<$Rhs> for Wrapping<F>
890 where
891 F: $Op<u32, Output = F>,
892 {
893 type Output = Wrapping<F>;
894 #[inline]
895 fn $op(self, other: $Rhs) -> Wrapping<F> {
896 let nbits = mem::size_of::<F>() as u32 * 8;
897 Wrapping((self.0).$op(other as u32 % nbits))
898 }
899 }
900 impl<'a, F> $Op<$Rhs> for &'a Wrapping<F>
901 where
902 &'a F: $Op<u32, Output = F>,
903 {
904 type Output = Wrapping<F>;
905 #[inline]
906 fn $op(self, other: $Rhs) -> Wrapping<F> {
907 let nbits = mem::size_of::<F>() as u32 * 8;
908 Wrapping((self.0).$op(other as u32 % nbits))
909 }
910 }
911 impl<'a, F> $Op<&'a $Rhs> for Wrapping<F>
912 where
913 F: $Op<u32, Output = F>,
914 {
915 type Output = Wrapping<F>;
916 #[inline]
917 fn $op(self, other: &$Rhs) -> Wrapping<F> {
918 let nbits = mem::size_of::<F>() as u32 * 8;
919 Wrapping((self.0).$op(*other as u32 % nbits))
920 }
921 }
922 impl<'a, 'b, F> $Op<&'a $Rhs> for &'b Wrapping<F>
923 where
924 &'b F: $Op<u32, Output = F>,
925 {
926 type Output = Wrapping<F>;
927 #[inline]
928 fn $op(self, other: &$Rhs) -> Wrapping<F> {
929 let nbits = mem::size_of::<F>() as u32 * 8;
930 Wrapping((self.0).$op(*other as u32 % nbits))
931 }
932 }
933 impl<F> $OpAssign<$Rhs> for Wrapping<F>
934 where
935 F: $OpAssign<u32>,
936 {
937 #[inline]
938 fn $op_assign(&mut self, other: $Rhs) {
939 let nbits = mem::size_of::<F>() as u32 * 8;
940 (self.0).$op_assign(other as u32 % nbits);
941 }
942 }
943 impl<'a, F> $OpAssign<&'a $Rhs> for Wrapping<F>
944 where
945 F: $OpAssign<u32>,
946 {
947 #[inline]
948 fn $op_assign(&mut self, other: &$Rhs) {
949 let nbits = mem::size_of::<F>() as u32 * 8;
950 (self.0).$op_assign(*other as u32 % nbits);
951 }
952 }
953 )* };
954}
955
956impl<F: Fixed> Neg for Wrapping<F> {
957 type Output = Wrapping<F>;
958 #[inline]
959 fn neg(self) -> Wrapping<F> {
960 Wrapping((self.0).wrapping_neg())
961 }
962}
963
964impl<'a, F: Fixed> Neg for &'a Wrapping<F> {
965 type Output = Wrapping<F>;
966 #[inline]
967 fn neg(self) -> Wrapping<F> {
968 Wrapping((self.0).wrapping_neg())
969 }
970}
971op! { wrapping_add, Add add, AddAssign add_assign }
972op! { wrapping_sub, Sub sub, SubAssign sub_assign }
973op! { wrapping_mul, Mul mul, MulAssign mul_assign }
974op! { wrapping_div, Div div, DivAssign div_assign }
975op! { rem, Rem rem, RemAssign rem_assign }
976
977impl<F> Not for Wrapping<F>
978where
979 F: Not<Output = F>,
980{
981 type Output = Wrapping<F>;
982 #[inline]
983 fn not(self) -> Wrapping<F> {
984 Wrapping((self.0).not())
985 }
986}
987impl<'a, F> Not for &'a Wrapping<F>
988where
989 &'a F: Not<Output = F>,
990{
991 type Output = Wrapping<F>;
992 #[inline]
993 fn not(self) -> Wrapping<F> {
994 Wrapping((self.0).not())
995 }
996}
997op_bitwise! { BitAnd bitand, BitAndAssign bitand_assign }
998op_bitwise! { BitOr bitor, BitOrAssign bitor_assign }
999op_bitwise! { BitXor bitxor, BitXorAssign bitxor_assign }
1000
1001op_shift! {
1002 Shl shl, ShlAssign shl_assign;
1003 i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
1004}
1005op_shift! {
1006 Shr shr, ShrAssign shr_assign;
1007 i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
1008}
1009
1010impl<F: Fixed> Sum<Wrapping<F>> for Wrapping<F> {
1011 fn sum<I>(iter: I) -> Wrapping<F>
1012 where
1013 I: Iterator<Item = Wrapping<F>>,
1014 {
1015 iter.fold(Wrapping(F::from_num(0)), Add::add)
1016 }
1017}
1018
1019impl<'a, F: 'a + Fixed> Sum<&'a Wrapping<F>> for Wrapping<F> {
1020 fn sum<I>(iter: I) -> Wrapping<F>
1021 where
1022 I: Iterator<Item = &'a Wrapping<F>>,
1023 {
1024 iter.fold(Wrapping(F::from_num(0)), Add::add)
1025 }
1026}
1027
1028impl<F: Fixed> Product<Wrapping<F>> for Wrapping<F> {
1029 fn product<I>(mut iter: I) -> Wrapping<F>
1030 where
1031 I: Iterator<Item = Wrapping<F>>,
1032 {
1033 match iter.next() {
1034 None => Wrapping(1.wrapping_to_fixed()),
1035 Some(first) => iter.fold(first, Mul::mul),
1036 }
1037 }
1038}
1039
1040impl<'a, F: 'a + Fixed> Product<&'a Wrapping<F>> for Wrapping<F> {
1041 fn product<I>(mut iter: I) -> Wrapping<F>
1042 where
1043 I: Iterator<Item = &'a Wrapping<F>>,
1044 {
1045 match iter.next() {
1046 None => Wrapping(1.wrapping_to_fixed()),
1047 Some(first) => iter.fold(*first, Mul::mul),
1048 }
1049 }
1050}
1051
1052// The following cannot be implemented for Wrapping<F> where F: Fixed,
1053// otherwise there will be a conflicting implementation error. For
1054// example we cannot implement both these without triggering E0119:
1055//
1056// impl<F: Fixed> Op<F::Bits> for Wrapping<F> { /* ... */ }
1057// impl<'a, F: Fixed> Op<&'a F::Bits> for Wrapping<F> { /* ... */ }
1058//
1059// To work around this, we provide implementations like this:
1060//
1061// impl<Frac> Op<i8> for Wrapping<FixedI8<Frac>> { /* ... */ }
1062// impl<'a, Frac> Op<&'a i8> for Wrapping<FixedI8<Frac>> { /* ... */ }
1063// impl<Frac> Op<i16> for Wrapping<FixedI16<Frac>> { /* ... */ }
1064// impl<'a, Frac> Op<&'a i16> for Wrapping<FixedI16<Frac>> { /* ... */ }
1065// ...
1066
1067macro_rules! op_bits {
1068 (
1069 $Fixed:ident($Bits:ident $(, $LeEqU:ident)*)::$wrapping:ident,
1070 $Op:ident $op:ident,
1071 $OpAssign:ident $op_assign:ident
1072 ) => {
1073 impl<Frac $(: $LeEqU)*> $Op<$Bits> for Wrapping<$Fixed<Frac>> {
1074 type Output = Wrapping<$Fixed<Frac>>;
1075 #[inline]
1076 fn $op(self, other: $Bits) -> Wrapping<$Fixed<Frac>> {
1077 Wrapping((self.0).$wrapping(other))
1078 }
1079 }
1080 impl<'a, Frac $(: $LeEqU)*> $Op<$Bits> for &'a Wrapping<$Fixed<Frac>> {
1081 type Output = Wrapping<$Fixed<Frac>>;
1082 #[inline]
1083 fn $op(self, other: $Bits) -> Wrapping<$Fixed<Frac>> {
1084 Wrapping((self.0).$wrapping(other))
1085 }
1086 }
1087 impl<'a, Frac $(: $LeEqU)*> $Op<&'a $Bits> for Wrapping<$Fixed<Frac>> {
1088 type Output = Wrapping<$Fixed<Frac>>;
1089 #[inline]
1090 fn $op(self, other: &$Bits) -> Wrapping<$Fixed<Frac>> {
1091 Wrapping((self.0).$wrapping(*other))
1092 }
1093 }
1094 impl<'a, 'b, Frac $(: $LeEqU)*> $Op<&'a $Bits> for &'b Wrapping<$Fixed<Frac>> {
1095 type Output = Wrapping<$Fixed<Frac>>;
1096 #[inline]
1097 fn $op(self, other: &$Bits) -> Wrapping<$Fixed<Frac>> {
1098 Wrapping((self.0).$wrapping(*other))
1099 }
1100 }
1101 impl<Frac $(: $LeEqU)*> $OpAssign<$Bits> for Wrapping<$Fixed<Frac>> {
1102 #[inline]
1103 fn $op_assign(&mut self, other: $Bits) {
1104 self.0 = (self.0).$wrapping(other);
1105 }
1106 }
1107 impl<'a, Frac $(: $LeEqU)*> $OpAssign<&'a $Bits> for Wrapping<$Fixed<Frac>> {
1108 #[inline]
1109 fn $op_assign(&mut self, other: &$Bits) {
1110 self.0 = (self.0).$wrapping(*other);
1111 }
1112 }
1113 };
1114}
1115
1116macro_rules! ops {
1117 ($Fixed:ident($Bits:ident, $LeEqU:ident)) => {
1118 op_bits! { $Fixed($Bits)::wrapping_mul_int, Mul mul, MulAssign mul_assign }
1119 op_bits! { $Fixed($Bits)::wrapping_div_int, Div div, DivAssign div_assign }
1120 op_bits! { $Fixed($Bits, $LeEqU)::rem, Rem rem, RemAssign rem_assign }
1121 };
1122}
1123ops! { FixedI8(i8, LeEqU8) }
1124ops! { FixedI16(i16, LeEqU16) }
1125ops! { FixedI32(i32, LeEqU32) }
1126ops! { FixedI64(i64, LeEqU64) }
1127ops! { FixedI128(i128, LeEqU128) }
1128ops! { FixedU8(u8, LeEqU8) }
1129ops! { FixedU16(u16, LeEqU16) }
1130ops! { FixedU32(u32, LeEqU32) }
1131ops! { FixedU64(u64, LeEqU64) }
1132ops! { FixedU128(u128, LeEqU128) }