surrealdb_core/sql/
number.rs

1use super::value::{TryAdd, TryDiv, TryFloatDiv, TryMul, TryNeg, TryPow, TryRem, TrySub};
2use crate::err::Error;
3use crate::fnc::util::math::ToFloat;
4use crate::sql::strand::Strand;
5use crate::sql::Value;
6use revision::revisioned;
7use rust_decimal::prelude::*;
8use serde::{Deserialize, Serialize};
9use std::cmp::Ordering;
10use std::f64::consts::PI;
11use std::fmt::Debug;
12use std::fmt::{self, Display, Formatter};
13use std::hash;
14use std::iter::Product;
15use std::iter::Sum;
16use std::ops::{self, Add, Div, Mul, Neg, Rem, Sub};
17
18pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Number";
19
20#[revisioned(revision = 1)]
21#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
22#[serde(rename = "$surrealdb::private::sql::Number")]
23#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
24#[non_exhaustive]
25pub enum Number {
26	Int(i64),
27	Float(f64),
28	Decimal(Decimal),
29	// Add new variants here
30}
31
32impl Default for Number {
33	fn default() -> Self {
34		Self::Int(0)
35	}
36}
37
38macro_rules! from_prim_ints {
39	($($int: ty),*) => {
40		$(
41			impl From<$int> for Number {
42				fn from(i: $int) -> Self {
43					Self::Int(i as i64)
44				}
45			}
46		)*
47	};
48}
49
50from_prim_ints!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
51
52impl From<f32> for Number {
53	fn from(f: f32) -> Self {
54		Self::Float(f as f64)
55	}
56}
57
58impl From<f64> for Number {
59	fn from(f: f64) -> Self {
60		Self::Float(f)
61	}
62}
63
64impl From<Decimal> for Number {
65	fn from(v: Decimal) -> Self {
66		Self::Decimal(v)
67	}
68}
69
70impl FromStr for Number {
71	type Err = ();
72	fn from_str(s: &str) -> Result<Self, Self::Err> {
73		Self::try_from(s)
74	}
75}
76
77impl TryFrom<String> for Number {
78	type Error = ();
79	fn try_from(v: String) -> Result<Self, Self::Error> {
80		Self::try_from(v.as_str())
81	}
82}
83
84impl TryFrom<Strand> for Number {
85	type Error = ();
86	fn try_from(v: Strand) -> Result<Self, Self::Error> {
87		Self::try_from(v.as_str())
88	}
89}
90
91impl TryFrom<&str> for Number {
92	type Error = ();
93	fn try_from(v: &str) -> Result<Self, Self::Error> {
94		// Attempt to parse as i64
95		match v.parse::<i64>() {
96			// Store it as an i64
97			Ok(v) => Ok(Self::Int(v)),
98			// It wasn't parsed as a i64 so parse as a float
99			_ => match f64::from_str(v) {
100				// Store it as a float
101				Ok(v) => Ok(Self::Float(v)),
102				// It wasn't parsed as a number
103				_ => Err(()),
104			},
105		}
106	}
107}
108
109macro_rules! try_into_prim {
110	// TODO: switch to one argument per int once https://github.com/rust-lang/rust/issues/29599 is stable
111	($($int: ty => $to_int: ident),*) => {
112		$(
113			impl TryFrom<Number> for $int {
114				type Error = Error;
115				fn try_from(value: Number) -> Result<Self, Self::Error> {
116					match value {
117						Number::Int(v) => match v.$to_int() {
118							Some(v) => Ok(v),
119							None => Err(Error::TryFrom(value.to_string(), stringify!($int))),
120						},
121						Number::Float(v) => match v.$to_int() {
122							Some(v) => Ok(v),
123							None => Err(Error::TryFrom(value.to_string(), stringify!($int))),
124						},
125						Number::Decimal(ref v) => match v.$to_int() {
126							Some(v) => Ok(v),
127							None => Err(Error::TryFrom(value.to_string(), stringify!($int))),
128						},
129					}
130				}
131			}
132		)*
133	};
134}
135
136try_into_prim!(
137	i8 => to_i8, i16 => to_i16, i32 => to_i32, i64 => to_i64, i128 => to_i128,
138	u8 => to_u8, u16 => to_u16, u32 => to_u32, u64 => to_u64, u128 => to_u128,
139	f32 => to_f32, f64 => to_f64
140);
141
142impl TryFrom<Number> for Decimal {
143	type Error = Error;
144	fn try_from(value: Number) -> Result<Self, Self::Error> {
145		match value {
146			Number::Int(v) => match Decimal::from_i64(v) {
147				Some(v) => Ok(v),
148				None => Err(Error::TryFrom(value.to_string(), "Decimal")),
149			},
150			Number::Float(v) => match Decimal::try_from(v) {
151				Ok(v) => Ok(v),
152				_ => Err(Error::TryFrom(value.to_string(), "Decimal")),
153			},
154			Number::Decimal(x) => Ok(x),
155		}
156	}
157}
158
159impl TryFrom<&Number> for f64 {
160	type Error = Error;
161
162	fn try_from(n: &Number) -> Result<Self, Self::Error> {
163		Ok(n.to_float())
164	}
165}
166
167impl TryFrom<&Number> for f32 {
168	type Error = Error;
169
170	fn try_from(n: &Number) -> Result<Self, Self::Error> {
171		n.to_float().to_f32().ok_or_else(|| Error::ConvertTo {
172			from: Value::Number(*n),
173			into: "f32".to_string(),
174		})
175	}
176}
177
178impl TryFrom<&Number> for i64 {
179	type Error = Error;
180
181	fn try_from(n: &Number) -> Result<Self, Self::Error> {
182		Ok(n.to_int())
183	}
184}
185impl TryFrom<&Number> for i32 {
186	type Error = Error;
187
188	fn try_from(n: &Number) -> Result<Self, Self::Error> {
189		n.to_int().to_i32().ok_or_else(|| Error::ConvertTo {
190			from: Value::Number(*n),
191			into: "i32".to_string(),
192		})
193	}
194}
195
196impl TryFrom<&Number> for i16 {
197	type Error = Error;
198
199	fn try_from(n: &Number) -> Result<Self, Self::Error> {
200		n.to_int().to_i16().ok_or_else(|| Error::ConvertTo {
201			from: Value::Number(*n),
202			into: "i16".to_string(),
203		})
204	}
205}
206
207impl Display for Number {
208	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
209		match self {
210			Number::Int(v) => Display::fmt(v, f),
211			Number::Float(v) => {
212				if v.is_finite() {
213					// Add suffix to distinguish between int and float
214					write!(f, "{v}f")
215				} else {
216					// Don't add suffix for NaN, inf, -inf
217					Display::fmt(v, f)
218				}
219			}
220			Number::Decimal(v) => write!(f, "{v}dec"),
221		}
222	}
223}
224
225impl Number {
226	// -----------------------------------
227	// Constants
228	// -----------------------------------
229
230	pub const NAN: Number = Number::Float(f64::NAN);
231
232	// -----------------------------------
233	// Simple number detection
234	// -----------------------------------
235
236	pub fn is_nan(&self) -> bool {
237		matches!(self, Number::Float(v) if v.is_nan())
238	}
239
240	pub fn is_int(&self) -> bool {
241		matches!(self, Number::Int(_))
242	}
243
244	pub fn is_float(&self) -> bool {
245		matches!(self, Number::Float(_))
246	}
247
248	pub fn is_decimal(&self) -> bool {
249		matches!(self, Number::Decimal(_))
250	}
251
252	pub fn is_integer(&self) -> bool {
253		match self {
254			Number::Int(_) => true,
255			Number::Float(v) => v.fract() == 0.0,
256			Number::Decimal(v) => v.is_integer(),
257		}
258	}
259
260	pub fn is_truthy(&self) -> bool {
261		match self {
262			Number::Int(v) => v != &0,
263			Number::Float(v) => v != &0.0,
264			Number::Decimal(v) => v != &Decimal::ZERO,
265		}
266	}
267
268	pub fn is_positive(&self) -> bool {
269		match self {
270			Number::Int(v) => v > &0,
271			Number::Float(v) => v > &0.0,
272			Number::Decimal(v) => v > &Decimal::ZERO,
273		}
274	}
275
276	pub fn is_negative(&self) -> bool {
277		match self {
278			Number::Int(v) => v < &0,
279			Number::Float(v) => v < &0.0,
280			Number::Decimal(v) => v < &Decimal::ZERO,
281		}
282	}
283
284	pub fn is_zero(&self) -> bool {
285		match self {
286			Number::Int(v) => v == &0,
287			Number::Float(v) => v == &0.0,
288			Number::Decimal(v) => v == &Decimal::ZERO,
289		}
290	}
291
292	pub fn is_zero_or_positive(&self) -> bool {
293		match self {
294			Number::Int(v) => v >= &0,
295			Number::Float(v) => v >= &0.0,
296			Number::Decimal(v) => v >= &Decimal::ZERO,
297		}
298	}
299
300	pub fn is_zero_or_negative(&self) -> bool {
301		match self {
302			Number::Int(v) => v <= &0,
303			Number::Float(v) => v <= &0.0,
304			Number::Decimal(v) => v <= &Decimal::ZERO,
305		}
306	}
307
308	// -----------------------------------
309	// Simple conversion of number
310	// -----------------------------------
311
312	pub fn as_usize(self) -> usize {
313		match self {
314			Number::Int(v) => v as usize,
315			Number::Float(v) => v as usize,
316			Number::Decimal(v) => v.try_into().unwrap_or_default(),
317		}
318	}
319
320	pub fn as_int(self) -> i64 {
321		match self {
322			Number::Int(v) => v,
323			Number::Float(v) => v as i64,
324			Number::Decimal(v) => v.try_into().unwrap_or_default(),
325		}
326	}
327
328	pub fn as_float(self) -> f64 {
329		match self {
330			Number::Int(v) => v as f64,
331			Number::Float(v) => v,
332			Number::Decimal(v) => v.try_into().unwrap_or_default(),
333		}
334	}
335
336	pub fn as_decimal(self) -> Decimal {
337		match self {
338			Number::Int(v) => Decimal::from(v),
339			Number::Float(v) => Decimal::try_from(v).unwrap_or_default(),
340			Number::Decimal(v) => v,
341		}
342	}
343
344	// -----------------------------------
345	// Complex conversion of number
346	// -----------------------------------
347
348	pub fn to_usize(&self) -> usize {
349		match self {
350			Number::Int(v) => *v as usize,
351			Number::Float(v) => *v as usize,
352			Number::Decimal(v) => v.to_usize().unwrap_or_default(),
353		}
354	}
355
356	pub fn to_int(&self) -> i64 {
357		match self {
358			Number::Int(v) => *v,
359			Number::Float(v) => *v as i64,
360			Number::Decimal(v) => v.to_i64().unwrap_or_default(),
361		}
362	}
363
364	pub fn to_float(&self) -> f64 {
365		match self {
366			Number::Int(v) => *v as f64,
367			Number::Float(v) => *v,
368			&Number::Decimal(v) => v.try_into().unwrap_or_default(),
369		}
370	}
371
372	pub fn to_decimal(&self) -> Decimal {
373		match self {
374			Number::Int(v) => Decimal::from(*v),
375			Number::Float(v) => Decimal::from_f64(*v).unwrap_or_default(),
376			Number::Decimal(v) => *v,
377		}
378	}
379
380	// -----------------------------------
381	//
382	// -----------------------------------
383
384	pub fn abs(self) -> Self {
385		match self {
386			Number::Int(v) => v.abs().into(),
387			Number::Float(v) => v.abs().into(),
388			Number::Decimal(v) => v.abs().into(),
389		}
390	}
391
392	pub fn acos(self) -> Self {
393		self.to_float().acos().into()
394	}
395
396	pub fn asin(self) -> Self {
397		self.to_float().asin().into()
398	}
399
400	pub fn atan(self) -> Self {
401		self.to_float().atan().into()
402	}
403
404	pub fn acot(self) -> Self {
405		(PI / 2.0 - self.atan().to_float()).into()
406	}
407
408	pub fn ceil(self) -> Self {
409		match self {
410			Number::Int(v) => v.into(),
411			Number::Float(v) => v.ceil().into(),
412			Number::Decimal(v) => v.ceil().into(),
413		}
414	}
415
416	pub fn clamp(self, min: Self, max: Self) -> Self {
417		match (self, min, max) {
418			(Number::Int(n), Number::Int(min), Number::Int(max)) => n.clamp(min, max).into(),
419			(Number::Decimal(n), min, max) => n.clamp(min.to_decimal(), max.to_decimal()).into(),
420			(Number::Float(n), min, max) => n.clamp(min.to_float(), max.to_float()).into(),
421			(Number::Int(n), min, max) => n.to_float().clamp(min.to_float(), max.to_float()).into(),
422		}
423	}
424
425	pub fn cos(self) -> Self {
426		self.to_float().cos().into()
427	}
428
429	pub fn cot(self) -> Self {
430		(1.0 / self.to_float().tan()).into()
431	}
432
433	pub fn deg2rad(self) -> Self {
434		self.to_float().to_radians().into()
435	}
436
437	pub fn floor(self) -> Self {
438		match self {
439			Number::Int(v) => v.into(),
440			Number::Float(v) => v.floor().into(),
441			Number::Decimal(v) => v.floor().into(),
442		}
443	}
444
445	fn lerp_f64(from: f64, to: f64, factor: f64) -> f64 {
446		from + factor * (to - from)
447	}
448
449	fn lerp_decimal(from: Decimal, to: Decimal, factor: Decimal) -> Decimal {
450		from + factor * (to - from)
451	}
452
453	pub fn lerp(self, from: Self, to: Self) -> Self {
454		match (self, from, to) {
455			(Number::Decimal(val), from, to) => {
456				Self::lerp_decimal(from.to_decimal(), to.to_decimal(), val).into()
457			}
458			(val, from, to) => {
459				Self::lerp_f64(from.to_float(), to.to_float(), val.to_float()).into()
460			}
461		}
462	}
463
464	fn repeat_f64(t: f64, m: f64) -> f64 {
465		(t - (t / m).floor() * m).clamp(0.0, m)
466	}
467
468	fn repeat_decimal(t: Decimal, m: Decimal) -> Decimal {
469		(t - (t / m).floor() * m).clamp(Decimal::ZERO, m)
470	}
471
472	pub fn lerp_angle(self, from: Self, to: Self) -> Self {
473		match (self, from, to) {
474			(Number::Decimal(val), from, to) => {
475				let from = from.to_decimal();
476				let to = to.to_decimal();
477				let mut dt = Self::repeat_decimal(to - from, Decimal::from(360));
478				if dt > Decimal::from(180) {
479					dt = Decimal::from(360) - dt;
480				}
481				Self::lerp_decimal(from, from + dt, val).into()
482			}
483			(val, from, to) => {
484				let val = val.to_float();
485				let from = from.to_float();
486				let to = to.to_float();
487				let mut dt = Self::repeat_f64(to - from, 360.0);
488				if dt > 180.0 {
489					dt = 360.0 - dt;
490				}
491				Self::lerp_f64(from, from + dt, val).into()
492			}
493		}
494	}
495
496	pub fn ln(self) -> Self {
497		self.to_float().ln().into()
498	}
499
500	pub fn log(self, base: Self) -> Self {
501		self.to_float().log(base.to_float()).into()
502	}
503
504	pub fn log2(self) -> Self {
505		self.to_float().log2().into()
506	}
507
508	pub fn log10(self) -> Self {
509		self.to_float().log10().into()
510	}
511
512	pub fn rad2deg(self) -> Self {
513		self.to_float().to_degrees().into()
514	}
515
516	pub fn round(self) -> Self {
517		match self {
518			Number::Int(v) => v.into(),
519			Number::Float(v) => v.round().into(),
520			Number::Decimal(v) => v.round().into(),
521		}
522	}
523
524	pub fn fixed(self, precision: usize) -> Number {
525		match self {
526			Number::Int(v) => format!("{v:.precision$}").try_into().unwrap_or_default(),
527			Number::Float(v) => format!("{v:.precision$}").try_into().unwrap_or_default(),
528			Number::Decimal(v) => v.round_dp(precision as u32).into(),
529		}
530	}
531
532	pub fn sign(self) -> Self {
533		match self {
534			Number::Int(n) => n.signum().into(),
535			Number::Float(n) => n.signum().into(),
536			Number::Decimal(n) => n.signum().into(),
537		}
538	}
539
540	pub fn sin(self) -> Self {
541		self.to_float().sin().into()
542	}
543
544	pub fn tan(self) -> Self {
545		self.to_float().tan().into()
546	}
547
548	pub fn sqrt(self) -> Self {
549		match self {
550			Number::Int(v) => (v as f64).sqrt().into(),
551			Number::Float(v) => v.sqrt().into(),
552			Number::Decimal(v) => v.sqrt().unwrap_or_default().into(),
553		}
554	}
555
556	pub fn pow(self, power: Number) -> Number {
557		match (self, power) {
558			(Number::Int(v), Number::Int(p)) => Number::Int(v.pow(p as u32)),
559			(Number::Decimal(v), Number::Int(p)) => v.powi(p).into(),
560			// TODO: (Number::Decimal(v), Number::Float(p)) => todo!(),
561			// TODO: (Number::Decimal(v), Number::Decimal(p)) => todo!(),
562			(v, p) => v.as_float().powf(p.as_float()).into(),
563		}
564	}
565}
566
567impl Eq for Number {}
568
569impl Ord for Number {
570	fn cmp(&self, other: &Self) -> Ordering {
571		fn total_cmp_f64(a: f64, b: f64) -> Ordering {
572			if a == 0.0 && b == 0.0 {
573				// -0.0 = 0.0
574				Ordering::Equal
575			} else {
576				// Handles NaN's
577				a.total_cmp(&b)
578			}
579		}
580
581		// Pick the greater number depending on whether it's positive.
582		macro_rules! greater {
583			($f:ident) => {
584				if $f.is_sign_positive() {
585					Ordering::Greater
586				} else {
587					Ordering::Less
588				}
589			};
590		}
591
592		match (self, other) {
593			(Number::Int(v), Number::Int(w)) => v.cmp(w),
594			(Number::Float(v), Number::Float(w)) => total_cmp_f64(*v, *w),
595			(Number::Decimal(v), Number::Decimal(w)) => v.cmp(w),
596			// ------------------------------
597			(Number::Int(v), Number::Float(w)) => {
598				// If the float is not finite, we don't need to compare it to the integer.
599				if !w.is_finite() {
600					return greater!(w).reverse();
601				}
602				// Cast int to i128 to avoid saturating.
603				let l = *v as i128;
604				// Cast the integer-part of the float to i128 to avoid saturating.
605				let r = *w as i128;
606				// Compare both integer parts.
607				match l.cmp(&r) {
608					// If the integer parts are equal then we need to compare the mantissa.
609					Ordering::Equal => total_cmp_f64(0.0, w.fract()),
610					// If the integer parts are not equal then we already know the correct ordering.
611					ordering => ordering,
612				}
613			}
614			(v @ Number::Float(_), w @ Number::Int(_)) => w.cmp(v).reverse(),
615			// ------------------------------
616			(Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).cmp(w),
617			(Number::Decimal(v), Number::Int(w)) => v.cmp(&Decimal::from(*w)),
618			// ------------------------------
619			(Number::Float(v), Number::Decimal(w)) => {
620				// Compare fractional parts of the float and decimal.
621				macro_rules! compare_fractions {
622					($l:ident, $r:ident) => {
623						match ($l == 0.0, $r == Decimal::ZERO) {
624							// If both numbers are zero, these are equal.
625							(true, true) => {
626								return Ordering::Equal;
627							}
628							// If only the float is zero, check the decimal's sign.
629							(true, false) => {
630								return greater!($r).reverse();
631							}
632							// If only the decimal is zero, check the float's sign.
633							(false, true) => {
634								return greater!($l);
635							}
636							// If neither is zero, continue checking the rest of the digits.
637							(false, false) => {
638								continue;
639							}
640						}
641					};
642				}
643				// If the float is not finite, we don't need to compare it to the decimal
644				if !v.is_finite() {
645					return greater!(v);
646				}
647				// Cast int to i128 to avoid saturating.
648				let l = *v as i128;
649				// Cast the integer-part of the decimal to i128.
650				let Ok(r) = i128::try_from(*w) else {
651					return greater!(w).reverse();
652				};
653				// Compare both integer parts.
654				match l.cmp(&r) {
655					// If the integer parts are equal then we need to compare the fractional parts.
656					Ordering::Equal => {
657						// We can't compare the fractional parts of floats with decimals reliably.
658						// Instead, we need to compare them as integers. To do this, we need to
659						// multiply the fraction with a number large enough to move some digits
660						// to the integer part of the float or decimal. The number should fit in
661						// 52 bits and be able to multiply f64 fractions between -1 and 1 without
662						// losing precision. Since we may need to do this repeatedly it helps if
663						// the number is as big as possible to reduce the number of
664						// iterations needed.
665						//
666						// This number is roughly 2 ^ 53 with the last digits truncated in order
667						// to make sure the fraction converges to 0 every time we multiply it.
668						// This is a magic number I found through my experiments so don't ask me
669						// the logic behind it :) Before changing this number, please make sure
670						// that the relevant tests aren't flaky after changing it.
671						const SAFE_MULTIPLIER: i64 = 9_007_199_254_740_000;
672						// Get the fractional part of the float.
673						let mut l = v.fract();
674						// Get the fractional part of the decimal.
675						let mut r = w.fract();
676						// Move the digits and compare them.
677						// This is very generous. For example, for our tests to pass we only need
678						// 3 iterations. This should be at least 6 to make sure we cover all
679						// possible decimals and floats.
680						for _ in 0..12 {
681							l *= SAFE_MULTIPLIER as f64;
682							r *= Decimal::new(SAFE_MULTIPLIER, 0);
683							// Cast the integer part of the decimal to i64. The fractions are always
684							// less than 1 so we know this will always be less than SAFE_MULTIPLIER.
685							match r.to_i64() {
686								Some(ref right) => match (l as i64).cmp(right) {
687									// If the integer parts are equal, we need to check the remaining
688									// fractional parts.
689									Ordering::Equal => {
690										// Drop the integer parts we already compared.
691										l = l.fract();
692										r = r.fract();
693										// Compare the fractional parts and decide whether to return
694										// or continue checking the next digits.
695										compare_fractions!(l, r);
696									}
697									ordering => {
698										// If the integer parts are not equal then we already know the
699										// correct ordering.
700										return ordering;
701									}
702								},
703								// This is technically unreachable. Reaching this part likely indicates
704								// a bug in `rust-decimal`'s `to_f64`'s implementation.
705								None => {
706									// We will assume the decimal is bigger or smaller depending on its
707									// sign.
708									return greater!(w).reverse();
709								}
710							}
711						}
712						// After our iterations, if we still haven't exhausted both fractions we will
713						// just treat them as equal. It should be impossible to reach this point after
714						// at least 6 iterations. We could use an infinite loop instead but this way
715						// we make sure the loop always exits.
716						Ordering::Equal
717					}
718					// If the integer parts are not equal then we already know the correct ordering.
719					ordering => ordering,
720				}
721			}
722			(v @ Number::Decimal(..), w @ Number::Float(..)) => w.cmp(v).reverse(),
723		}
724	}
725}
726
727// Warning: Equal numbers may have different hashes, which violates
728// the invariants of certain collections!
729impl hash::Hash for Number {
730	fn hash<H: hash::Hasher>(&self, state: &mut H) {
731		match self {
732			Number::Int(v) => v.hash(state),
733			Number::Float(v) => v.to_bits().hash(state),
734			Number::Decimal(v) => v.hash(state),
735		}
736	}
737}
738
739impl PartialEq for Number {
740	fn eq(&self, other: &Self) -> bool {
741		fn total_eq_f64(a: f64, b: f64) -> bool {
742			a.to_bits().eq(&b.to_bits()) || (a == 0.0 && b == 0.0)
743		}
744
745		match (self, other) {
746			(Number::Int(v), Number::Int(w)) => v.eq(w),
747			(Number::Float(v), Number::Float(w)) => total_eq_f64(*v, *w),
748			(Number::Decimal(v), Number::Decimal(w)) => v.eq(w),
749			// ------------------------------
750			(v @ Number::Int(_), w @ Number::Float(_)) => v.cmp(w) == Ordering::Equal,
751			(v @ Number::Float(_), w @ Number::Int(_)) => v.cmp(w) == Ordering::Equal,
752			// ------------------------------
753			(Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).eq(w),
754			(Number::Decimal(v), Number::Int(w)) => v.eq(&Decimal::from(*w)),
755			// ------------------------------
756			(v @ Number::Float(_), w @ Number::Decimal(_)) => v.cmp(w) == Ordering::Equal,
757			(v @ Number::Decimal(_), w @ Number::Float(_)) => v.cmp(w) == Ordering::Equal,
758		}
759	}
760}
761
762impl PartialOrd for Number {
763	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
764		Some(self.cmp(other))
765	}
766}
767
768macro_rules! impl_simple_try_op {
769	($trt:ident, $fn:ident, $unchecked:ident, $checked:ident) => {
770		impl $trt for Number {
771			type Output = Self;
772			fn $fn(self, other: Self) -> Result<Self, Error> {
773				Ok(match (self, other) {
774					(Number::Int(v), Number::Int(w)) => Number::Int(
775						v.$checked(w).ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
776					),
777					(Number::Float(v), Number::Float(w)) => Number::Float(v.$unchecked(w)),
778					(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(
779						v.$checked(w).ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
780					),
781					(Number::Int(v), Number::Float(w)) => Number::Float((v as f64).$unchecked(w)),
782					(Number::Float(v), Number::Int(w)) => Number::Float(v.$unchecked(w as f64)),
783					(v, w) => Number::Decimal(
784						v.to_decimal()
785							.$checked(w.to_decimal())
786							.ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
787					),
788				})
789			}
790		}
791	};
792}
793
794impl_simple_try_op!(TryAdd, try_add, add, checked_add);
795impl_simple_try_op!(TrySub, try_sub, sub, checked_sub);
796impl_simple_try_op!(TryMul, try_mul, mul, checked_mul);
797impl_simple_try_op!(TryDiv, try_div, div, checked_div);
798impl_simple_try_op!(TryRem, try_rem, rem, checked_rem);
799
800impl TryPow for Number {
801	type Output = Self;
802	fn try_pow(self, power: Self) -> Result<Self, Error> {
803		Ok(match (self, power) {
804			(Self::Int(v), Self::Int(p)) => Self::Int(match v {
805				0 => match p.cmp(&0) {
806					// 0^(-x)
807					Ordering::Less => return Err(Error::TryPow(v.to_string(), p.to_string())),
808					// 0^0
809					Ordering::Equal => 1,
810					// 0^x
811					Ordering::Greater => 0,
812				},
813				// 1^p
814				1 => 1,
815				-1 => {
816					if p % 2 == 0 {
817						// (-1)^even
818						1
819					} else {
820						// (-1)^odd
821						-1
822					}
823				}
824				// try_into may cause an error, which would be wrong for the above cases.
825				_ => p
826					.try_into()
827					.ok()
828					.and_then(|p| v.checked_pow(p))
829					.ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
830			}),
831			(Self::Decimal(v), Self::Int(p)) => Self::Decimal(
832				v.checked_powi(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
833			),
834			(Self::Decimal(v), Self::Float(p)) => Self::Decimal(
835				v.checked_powf(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
836			),
837			(Self::Decimal(v), Self::Decimal(p)) => Self::Decimal(
838				v.checked_powd(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
839			),
840			(v, p) => v.as_float().powf(p.as_float()).into(),
841		})
842	}
843}
844
845impl TryNeg for Number {
846	type Output = Self;
847
848	fn try_neg(self) -> Result<Self::Output, Error> {
849		Ok(match self {
850			Self::Int(n) => {
851				Number::Int(n.checked_neg().ok_or_else(|| Error::TryNeg(n.to_string()))?)
852			}
853			Self::Float(n) => Number::Float(-n),
854			Self::Decimal(n) => Number::Decimal(-n),
855		})
856	}
857}
858
859impl TryFloatDiv for Number {
860	type Output = Self;
861	fn try_float_div(self, other: Self) -> Result<Self, Error> {
862		Ok(match (self, other) {
863			(Number::Int(v), Number::Int(w)) => {
864				let quotient = (v as f64).div(w as f64);
865				if quotient.fract() != 0.0 {
866					return Ok(Number::Float(quotient));
867				}
868				Number::Int(
869					v.checked_div(w).ok_or_else(|| Error::TryDiv(v.to_string(), w.to_string()))?,
870				)
871			}
872			(v, w) => v.try_div(w)?,
873		})
874	}
875}
876
877impl ops::Add for Number {
878	type Output = Self;
879	fn add(self, other: Self) -> Self {
880		match (self, other) {
881			(Number::Int(v), Number::Int(w)) => Number::Int(v + w),
882			(Number::Float(v), Number::Float(w)) => Number::Float(v + w),
883			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v + w),
884			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 + w),
885			(Number::Float(v), Number::Int(w)) => Number::Float(v + w as f64),
886			(v, w) => Number::from(v.as_decimal() + w.as_decimal()),
887		}
888	}
889}
890
891impl<'b> ops::Add<&'b Number> for &Number {
892	type Output = Number;
893	fn add(self, other: &'b Number) -> Number {
894		match (self, other) {
895			(Number::Int(v), Number::Int(w)) => Number::Int(v + w),
896			(Number::Float(v), Number::Float(w)) => Number::Float(v + w),
897			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v + w),
898			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 + w),
899			(Number::Float(v), Number::Int(w)) => Number::Float(v + *w as f64),
900			(v, w) => Number::from(v.to_decimal() + w.to_decimal()),
901		}
902	}
903}
904
905impl ops::Sub for Number {
906	type Output = Self;
907	fn sub(self, other: Self) -> Self {
908		match (self, other) {
909			(Number::Int(v), Number::Int(w)) => Number::Int(v - w),
910			(Number::Float(v), Number::Float(w)) => Number::Float(v - w),
911			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v - w),
912			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 - w),
913			(Number::Float(v), Number::Int(w)) => Number::Float(v - w as f64),
914			(v, w) => Number::from(v.as_decimal() - w.as_decimal()),
915		}
916	}
917}
918
919impl<'b> ops::Sub<&'b Number> for &Number {
920	type Output = Number;
921	fn sub(self, other: &'b Number) -> Number {
922		match (self, other) {
923			(Number::Int(v), Number::Int(w)) => Number::Int(v - w),
924			(Number::Float(v), Number::Float(w)) => Number::Float(v - w),
925			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v - w),
926			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 - w),
927			(Number::Float(v), Number::Int(w)) => Number::Float(v - *w as f64),
928			(v, w) => Number::from(v.to_decimal() - w.to_decimal()),
929		}
930	}
931}
932
933impl ops::Mul for Number {
934	type Output = Self;
935	fn mul(self, other: Self) -> Self {
936		match (self, other) {
937			(Number::Int(v), Number::Int(w)) => Number::Int(v * w),
938			(Number::Float(v), Number::Float(w)) => Number::Float(v * w),
939			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v * w),
940			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 * w),
941			(Number::Float(v), Number::Int(w)) => Number::Float(v * w as f64),
942			(v, w) => Number::from(v.as_decimal() * w.as_decimal()),
943		}
944	}
945}
946
947impl<'b> ops::Mul<&'b Number> for &Number {
948	type Output = Number;
949	fn mul(self, other: &'b Number) -> Number {
950		match (self, other) {
951			(Number::Int(v), Number::Int(w)) => Number::Int(v * w),
952			(Number::Float(v), Number::Float(w)) => Number::Float(v * w),
953			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v * w),
954			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 * w),
955			(Number::Float(v), Number::Int(w)) => Number::Float(v * *w as f64),
956			(v, w) => Number::from(v.to_decimal() * w.to_decimal()),
957		}
958	}
959}
960
961impl ops::Div for Number {
962	type Output = Self;
963	fn div(self, other: Self) -> Self {
964		match (self, other) {
965			(Number::Int(v), Number::Int(w)) => Number::Int(v / w),
966			(Number::Float(v), Number::Float(w)) => Number::Float(v / w),
967			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v / w),
968			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 / w),
969			(Number::Float(v), Number::Int(w)) => Number::Float(v / w as f64),
970			(v, w) => Number::from(v.as_decimal() / w.as_decimal()),
971		}
972	}
973}
974
975impl<'b> ops::Div<&'b Number> for &Number {
976	type Output = Number;
977	fn div(self, other: &'b Number) -> Number {
978		match (self, other) {
979			(Number::Int(v), Number::Int(w)) => Number::Int(v / w),
980			(Number::Float(v), Number::Float(w)) => Number::Float(v / w),
981			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v / w),
982			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 / w),
983			(Number::Float(v), Number::Int(w)) => Number::Float(v / *w as f64),
984			(v, w) => Number::from(v.to_decimal() / w.to_decimal()),
985		}
986	}
987}
988
989impl Neg for Number {
990	type Output = Self;
991
992	fn neg(self) -> Self::Output {
993		match self {
994			Self::Int(n) => Number::Int(-n),
995			Self::Float(n) => Number::Float(-n),
996			Self::Decimal(n) => Number::Decimal(-n),
997		}
998	}
999}
1000
1001// ------------------------------
1002
1003impl Sum<Self> for Number {
1004	fn sum<I>(iter: I) -> Number
1005	where
1006		I: Iterator<Item = Self>,
1007	{
1008		iter.fold(Number::Int(0), |a, b| a + b)
1009	}
1010}
1011
1012impl<'a> Sum<&'a Self> for Number {
1013	fn sum<I>(iter: I) -> Number
1014	where
1015		I: Iterator<Item = &'a Self>,
1016	{
1017		iter.fold(Number::Int(0), |a, b| &a + b)
1018	}
1019}
1020
1021impl Product<Self> for Number {
1022	fn product<I>(iter: I) -> Number
1023	where
1024		I: Iterator<Item = Self>,
1025	{
1026		iter.fold(Number::Int(1), |a, b| a * b)
1027	}
1028}
1029
1030impl<'a> Product<&'a Self> for Number {
1031	fn product<I>(iter: I) -> Number
1032	where
1033		I: Iterator<Item = &'a Self>,
1034	{
1035		iter.fold(Number::Int(1), |a, b| &a * b)
1036	}
1037}
1038
1039#[non_exhaustive]
1040pub struct Sorted<T>(pub T);
1041
1042pub trait Sort {
1043	fn sorted(&mut self) -> Sorted<&Self>
1044	where
1045		Self: Sized;
1046}
1047
1048impl Sort for Vec<Number> {
1049	fn sorted(&mut self) -> Sorted<&Vec<Number>> {
1050		self.sort();
1051		Sorted(self)
1052	}
1053}
1054
1055impl ToFloat for Number {
1056	fn to_float(&self) -> f64 {
1057		self.to_float()
1058	}
1059}
1060
1061#[cfg(test)]
1062mod tests {
1063	use std::cmp::Ordering;
1064
1065	use rand::seq::SliceRandom;
1066	use rand::thread_rng;
1067	use rand::Rng;
1068	use rust_decimal::Decimal;
1069
1070	use super::Number;
1071	use super::TryFloatDiv;
1072	#[test]
1073	fn test_try_float_div() {
1074		let (sum_one, count_one) = (Number::Int(5), Number::Int(2));
1075		assert_eq!(sum_one.try_float_div(count_one).unwrap(), Number::Float(2.5));
1076		// i64::MIN
1077
1078		let (sum_two, count_two) = (Number::Int(10), Number::Int(5));
1079		assert_eq!(sum_two.try_float_div(count_two).unwrap(), Number::Int(2));
1080
1081		let (sum_three, count_three) = (Number::Float(6.3), Number::Int(3));
1082		assert_eq!(sum_three.try_float_div(count_three).unwrap(), Number::Float(2.1));
1083	}
1084
1085	#[test]
1086	fn ord_test() {
1087		let a = Number::Float(-f64::NAN);
1088		let b = Number::Float(-f64::INFINITY);
1089		let c = Number::Float(1f64);
1090		let d = Number::Decimal(Decimal::from_str_exact("1.0000000000000000000000000002").unwrap());
1091		let e = Number::Decimal(Decimal::from_str_exact("1.1").unwrap());
1092		let f = Number::Float(1.1f64);
1093		let g = Number::Float(1.5f64);
1094		let h = Number::Decimal(Decimal::from_str_exact("1.5").unwrap());
1095		let i = Number::Float(f64::INFINITY);
1096		let j = Number::Float(f64::NAN);
1097		let original = vec![a, b, c, d, e, f, g, h, i, j];
1098		let mut copy = original.clone();
1099		let mut rng = thread_rng();
1100		copy.shuffle(&mut rng);
1101		copy.sort();
1102		assert_eq!(original, copy);
1103	}
1104
1105	#[test]
1106	fn ord_fuzz() {
1107		fn random_number() -> Number {
1108			let mut rng = thread_rng();
1109			match rng.gen_range(0..3) {
1110				0 => Number::Int(rng.gen()),
1111				1 => Number::Float(f64::from_bits(rng.gen())),
1112				_ => Number::Decimal(Number::Float(f64::from_bits(rng.gen())).as_decimal()),
1113			}
1114		}
1115
1116		// TODO: Use std library once stable https://doc.rust-lang.org/std/primitive.f64.html#method.next_down
1117		fn next_down(n: f64) -> f64 {
1118			const TINY_BITS: u64 = 0x1; // Smallest positive f64.
1119			const CLEAR_SIGN_MASK: u64 = 0x7fff_ffff_ffff_ffff;
1120
1121			let bits = n.to_bits();
1122			if n.is_nan() || bits == f64::INFINITY.to_bits() {
1123				return n;
1124			}
1125
1126			let abs = bits & CLEAR_SIGN_MASK;
1127			let next_bits = if abs == 0 {
1128				TINY_BITS
1129			} else if bits == abs {
1130				bits + 1
1131			} else {
1132				bits - 1
1133			};
1134			f64::from_bits(next_bits)
1135		}
1136
1137		fn random_permutation(number: Number) -> Number {
1138			let mut rng = thread_rng();
1139			let value = match rng.gen_range(0..4) {
1140				0 => number + Number::from(rng.gen::<f64>()),
1141				1 if !matches!(number, Number::Int(i64::MIN)) => number * Number::from(-1),
1142				2 => Number::Float(next_down(number.as_float())),
1143				_ => number,
1144			};
1145			match rng.gen_range(0..3) {
1146				0 => Number::Int(value.as_int()),
1147				1 => Number::Float(value.as_float()),
1148				_ => Number::Decimal(value.as_decimal()),
1149			}
1150		}
1151
1152		fn assert_partial_ord(x: Number, y: Number) {
1153			// PartialOrd requirements
1154			assert_eq!(x == y, x.partial_cmp(&y) == Some(Ordering::Equal), "{x:?} {y:?}");
1155
1156			// Ord consistent with PartialOrd
1157			assert_eq!(x.partial_cmp(&y), Some(x.cmp(&y)), "{x:?} {y:?}");
1158		}
1159
1160		fn assert_consistent(a: Number, b: Number, c: Number) {
1161			assert_partial_ord(a, b);
1162			assert_partial_ord(b, c);
1163			assert_partial_ord(c, a);
1164
1165			// Transitive property (without the fix, these can fail)
1166			if a == b && b == c {
1167				assert_eq!(a, c, "{a:?} {b:?} {c:?}");
1168			}
1169			if a != b && b == c {
1170				assert_ne!(a, c, "{a:?} {b:?} {c:?}");
1171			}
1172			if a < b && b < c {
1173				assert!(a < c, "{a:?} {b:?} {c:?}");
1174			}
1175			if a > b && b > c {
1176				assert!(a > c, "{a:?} {b:?} {c:?}");
1177			}
1178
1179			// Duality
1180			assert_eq!(a == b, b == a, "{a:?} {b:?}");
1181			assert_eq!(a < b, b > a, "{a:?} {b:?}");
1182		}
1183
1184		for _ in 0..100000 {
1185			let base = random_number();
1186			let a = random_permutation(base);
1187			let b = random_permutation(a);
1188			let c = random_permutation(b);
1189			assert_consistent(a, b, c);
1190		}
1191	}
1192}