fixed_num/ops.rs
1pub use std::ops::Add;
2pub use std::ops::Sub;
3pub use std::ops::Mul;
4pub use std::ops::Div;
5pub use std::ops::Rem;
6pub use std::ops::AddAssign;
7pub use std::ops::SubAssign;
8pub use std::ops::MulAssign;
9pub use std::ops::DivAssign;
10pub use std::ops::Neg;
11
12// ==============
13// === Traits ===
14// ==============
15
16pub mod traits {
17 pub use std::ops::Add as _;
18 pub use std::ops::Sub as _;
19 pub use std::ops::Mul as _;
20 pub use std::ops::Div as _;
21 pub use std::ops::Rem as _;
22 pub use std::ops::AddAssign as _;
23 pub use std::ops::SubAssign as _;
24 pub use std::ops::MulAssign as _;
25 pub use std::ops::DivAssign as _;
26 pub use std::ops::Neg as _;
27 pub use super::HasMax as _;
28 pub use super::HasMin as _;
29 pub use super::Signum as _;
30 pub use super::Abs as _;
31 pub use super::UncheckedAdd as _;
32 pub use super::CheckedAdd as _;
33 pub use super::SaturatingAdd as _;
34 pub use super::UncheckedSub as _;
35 pub use super::CheckedSub as _;
36 pub use super::SaturatingSub as _;
37 pub use super::UncheckedMul as _;
38 pub use super::CheckedMul as _;
39 pub use super::SaturatingMul as _;
40 pub use super::UncheckedDiv as _;
41 pub use super::CheckedDiv as _;
42 pub use super::SaturatingDiv as _;
43 pub use super::Trunc as _;
44 pub use super::TruncTo as _;
45 pub use super::Floor as _;
46 pub use super::FloorTo as _;
47 pub use super::Ceil as _;
48 pub use super::CeilTo as _;
49 pub use super::Round as _;
50 pub use super::RoundTo as _;
51 pub use super::UncheckedSqrt as _;
52 pub use super::CheckedSqrt as _;
53 pub use super::UncheckedPow as _;
54 pub use super::CheckedPow as _;
55 pub use super::UncheckedLog10Floor as _;
56 pub use super::CheckedLog10Floor as _;
57 pub use super::UncheckedLn as _;
58 pub use super::CheckedLn as _;
59}
60
61// ==============
62// === HasMax ===
63// ==============
64
65/// ✅ Checks if `self` is the maximum value.
66///
67/// # Panics
68///
69/// This function never panics.
70#[cfg_attr(nightly, const_trait)]
71pub trait HasMax: Sized {
72 const MAX: Self;
73 #[allow(clippy::wrong_self_convention)]
74 fn is_max(self) -> bool;
75}
76
77// ==============
78// === HasMin ===
79// ==============
80
81/// ✅ Checks if `self` is the minimum value.
82///
83/// # Panics
84///
85/// This function never panics.
86#[cfg_attr(nightly, const_trait)]
87pub trait HasMin: Sized {
88 const MIN: Self;
89 #[allow(clippy::wrong_self_convention)]
90 fn is_min(self) -> bool;
91}
92
93// ==============
94// === Signum ===
95// ==============
96
97/// ✅ The sign of the number.
98///
99/// Returns:
100/// - `1.0` if positive,
101/// - `0.0` if zero,
102/// - `-1.0` if negative.
103///
104/// # Panics
105///
106/// This function never panics.
107#[cfg_attr(nightly, const_trait)]
108pub trait Signum {
109 fn signum(self) -> Self;
110 fn signum_i128(self) -> i128;
111}
112
113// ===========
114// === Abs ===
115// ===========
116
117/// ✅ The absolute value of `self`.
118///
119/// # Panics
120///
121/// This function never panics. If the value is the minimum representable number, it returns the
122/// nearest valid value (e.g. `Self::MAX`).
123#[cfg_attr(nightly, const_trait)]
124pub trait Abs {
125 fn abs(self) -> Self;
126}
127
128// ===========
129// === Add ===
130// ===========
131
132/// Addition without checking for overflow.
133///
134/// # Panics
135///
136/// Panics if the result overflows.
137#[cfg_attr(nightly, const_trait)]
138pub trait UncheckedAdd<Rhs = Self> {
139 type Output;
140 fn unchecked_add(self, rhs: Rhs) -> Self::Output;
141}
142
143/// ✅ Checked addition. Returns `None` if the result overflows.
144///
145/// # Panics
146///
147/// This function never panics.
148#[cfg_attr(nightly, const_trait)]
149pub trait CheckedAdd<Rhs = Self> {
150 type Output;
151 fn checked_add(self, rhs: Rhs) -> Option<Self::Output>;
152}
153
154/// ✅ Saturating addition. Clamps the result on overflow.
155///
156/// # Panics
157///
158/// This function never panics.
159#[cfg_attr(nightly, const_trait)]
160pub trait SaturatingAdd<Rhs = Self> {
161 type Output;
162 fn saturating_add(self, rhs: Rhs) -> Self::Output;
163}
164
165// ===========
166// === Sub ===
167// ===========
168
169/// Subtraction without checking for overflow.
170///
171/// # Panics
172///
173/// Panics if the result overflows.
174#[cfg_attr(nightly, const_trait)]
175pub trait UncheckedSub<Rhs = Self> {
176 type Output;
177 fn unchecked_sub(self, rhs: Rhs) -> Self::Output;
178}
179
180/// ✅ Checked subtraction. Returns `None` if the result overflows.
181///
182/// # Panics
183///
184/// This function never panics.
185#[cfg_attr(nightly, const_trait)]
186pub trait CheckedSub<Rhs = Self> {
187 type Output;
188 fn checked_sub(self, rhs: Rhs) -> Option<Self::Output>;
189}
190
191/// ✅ Saturating subtraction. Clamps the result on overflow.
192///
193/// # Panics
194///
195/// This function never panics.
196#[cfg_attr(nightly, const_trait)]
197pub trait SaturatingSub<Rhs = Self> {
198 type Output;
199 fn saturating_sub(self, rhs: Rhs) -> Self::Output;
200}
201
202// ===========
203// === Mul ===
204// ===========
205
206/// Multiplication without checking for overflow.
207///
208/// # Panics
209///
210/// Panics if the result overflows.
211#[cfg_attr(nightly, const_trait)]
212pub trait UncheckedMul<Rhs = Self> {
213 type Output;
214 fn unchecked_mul(self, rhs: Rhs) -> Self::Output;
215}
216
217/// ✅ Checked multiplication. Returns `None` if the result overflows.
218///
219/// # Panics
220///
221/// This function never panics.
222#[cfg_attr(nightly, const_trait)]
223pub trait CheckedMul<Rhs = Self> {
224 type Output;
225 fn checked_mul(self, rhs: Rhs) -> Option<Self::Output>;
226}
227
228/// ✅ Saturating multiplication. Clamps the result on overflow.
229///
230/// # Panics
231///
232/// This function never panics.
233#[cfg_attr(nightly, const_trait)]
234pub trait SaturatingMul<Rhs = Self> {
235 type Output;
236 fn saturating_mul(self, rhs: Rhs) -> Self::Output;
237}
238
239// ===========
240// === Div ===
241// ===========
242
243/// Division without checking for division by zero or overflow.
244///
245/// # Panics
246///
247/// Panics if dividing by zero or if the result overflows.
248#[cfg_attr(nightly, const_trait)]
249pub trait UncheckedDiv<Rhs = Self> {
250 type Output;
251 fn unchecked_div(self, rhs: Rhs) -> Self::Output;
252}
253
254/// ✅ Checked division. Returns `None` on division by zero or overflow.
255///
256/// # Panics
257///
258/// This function never panics.
259#[cfg_attr(nightly, const_trait)]
260pub trait CheckedDiv<Rhs = Self> {
261 type Output;
262 fn checked_div(self, rhs: Rhs) -> Option<Self::Output>;
263}
264
265/// ✅ Saturating division. Returns `Self::MAX` or `Self::MIN` if division by zero or overflow
266/// occurs.
267///
268/// # Panics
269///
270/// This function never panics.
271#[cfg_attr(nightly, const_trait)]
272pub trait SaturatingDiv<Rhs = Self> {
273 type Output;
274 fn saturating_div(self, rhs: Rhs) -> Self::Output;
275}
276
277// =============
278// === Trunc ===
279// =============
280
281/// ✅ Truncates fractional digits, rounding toward zero.
282///
283/// # Panics
284///
285/// This function never panics.
286#[cfg_attr(nightly, const_trait)]
287pub trait Trunc {
288 fn trunc(self) -> Self;
289}
290
291/// ✅ Truncates to the specified number of fractional digits.
292///
293/// # Panics
294///
295/// This function never panics.
296#[cfg_attr(nightly, const_trait)]
297pub trait TruncTo {
298 fn trunc_to(self, digits: i64) -> Self;
299}
300
301// =============
302// === Floor ===
303// =============
304
305/// ✅ Rounds the number toward negative infinity if the result is representable. If rounding would
306/// cause an overflow, returns the original value unchanged.
307///
308/// # Panics
309///
310/// This function never panics.
311#[cfg_attr(nightly, const_trait)]
312pub trait Floor {
313 fn floor(self) -> Self;
314}
315
316/// ✅ Rounds the number toward negative infinity to the specified number of fractional digits. If
317/// rounding would cause an overflow, returns the original value unchanged.
318///
319/// # Panics
320///
321/// This function never panics.
322#[cfg_attr(nightly, const_trait)]
323pub trait FloorTo {
324 fn floor_to(self, digits: i64) -> Self;
325}
326
327// ============
328// === Ceil ===
329// ============
330
331/// ✅ Rounds the number toward positive infinity if the result is representable. If rounding would
332/// cause an overflow, returns the original value unchanged.
333///
334/// # Panics
335///
336/// This function never panics.
337#[cfg_attr(nightly, const_trait)]
338pub trait Ceil {
339 fn ceil(self) -> Self;
340}
341
342/// ✅ Rounds the number toward positive infinity to the specified number of fractional digits. If
343/// rounding would cause an overflow, returns the original value unchanged.
344///
345/// # Panics
346///
347/// This function never panics.
348#[cfg_attr(nightly, const_trait)]
349pub trait CeilTo {
350 fn ceil_to(self, digits: i64) -> Self;
351}
352
353// =============
354// === Round ===
355// =============
356
357/// ✅ Rounds the number to the nearest integer, away from zero on tie. If rounding would cause an
358/// overflow, returns the nearest representable result instead.
359///
360/// # Examples
361///
362/// - `...123.4` -> `...123`
363/// - `...123.5` -> `...124`
364/// - `...123.6` -> `...124`
365/// - `...123.6` -> `...123` if `...124` is not representable.
366///
367/// # Panics
368///
369/// This function never panics.
370#[cfg_attr(nightly, const_trait)]
371pub trait Round {
372 fn round(self) -> Self;
373}
374
375/// ✅ Rounds the number to the nearest value with the specified number of fractional digits, away
376/// from zero on tie. If rounding would cause an overflow, returns the closest representable result
377/// instead.
378///
379/// # Panics
380///
381/// This function never panics.
382#[cfg_attr(nightly, const_trait)]
383pub trait RoundTo {
384 fn round_to(self, digits: i64) -> Self;
385}
386
387// ============
388// === Sqrt ===
389// ============
390
391/// Returns the square root of `self` without checking the input.
392///
393/// # Panics
394///
395/// Panics if `self` is negative.
396#[cfg_attr(nightly, const_trait)]
397pub trait UncheckedSqrt {
398 fn unchecked_sqrt(self) -> Self;
399}
400
401/// ✅ Returns the square root of `self`, or `None` if `self` is negative.
402///
403/// # Panics
404///
405/// This function never panics.
406#[cfg_attr(nightly, const_trait)]
407pub trait CheckedSqrt: Sized {
408 fn checked_sqrt(self) -> Option<Self>;
409}
410
411// ===========
412// === Pow ===
413// ===========
414
415/// Raises `self` to the power of `exp` without checking for overflow or invalid input.
416///
417/// # Panics
418///
419/// Panics on overflow or if `exp` is negative and `self` is zero.
420#[cfg_attr(nightly, const_trait)]
421pub trait UncheckedPow<Exp = Self> {
422 type Output;
423 fn unchecked_pow(self, exp: Exp) -> Self::Output;
424}
425
426/// ✅ aises `self` to the power of `exp`, returning `None` on overflow or invalid input.
427///
428/// # Panics
429///
430/// This function never panics.
431#[cfg_attr(nightly, const_trait)]
432pub trait CheckedPow<Rhs = Self> {
433 type Output;
434 fn checked_pow(self, exp: Rhs) -> Option<Self::Output>;
435}
436
437// ==================
438// === Log10Floor ===
439// ==================
440
441/// Returns the base-10 logarithm of `self`, rounded down to the nearest integer.
442///
443/// # Panics
444///
445/// Panics if `self` is zero or negative.
446#[cfg_attr(nightly, const_trait)]
447pub trait UncheckedLog10Floor {
448 fn unchecked_log10_floor(self) -> Self;
449}
450
451/// ✅ Returns the base-10 logarithm of `self`, rounded down to the nearest integer,
452/// or `None` if `self` is zero or negative.
453///
454/// # Panics
455///
456/// This function never panics.
457#[cfg_attr(nightly, const_trait)]
458pub trait CheckedLog10Floor: Sized {
459 fn checked_log10_floor(self) -> Option<Self>;
460}
461
462// ==========
463// === Ln ===
464// ==========
465
466/// Returns the natural logarithm of `self`.
467///
468/// # Panics
469///
470/// Panics if `self` is zero or negative.
471#[cfg_attr(nightly, const_trait)]
472pub trait UncheckedLn {
473 fn unchecked_ln(self) -> Self;
474}
475
476/// ✅ Returns the natural logarithm of `self`, or `None` if `self` is zero or negative.
477///
478/// # Panics
479///
480/// This function never panics.
481#[cfg_attr(nightly, const_trait)]
482pub trait CheckedLn: Sized {
483 fn checked_ln(self) -> Option<Self>;
484}