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