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 checked_abs(self) -> Option<Self> {
393		match self {
394			Number::Int(v) => v.checked_abs().map(|x| x.into()),
395			Number::Float(v) => Some(v.abs().into()),
396			Number::Decimal(v) => Some(v.abs().into()),
397		}
398	}
399
400	pub fn acos(self) -> Self {
401		self.to_float().acos().into()
402	}
403
404	pub fn asin(self) -> Self {
405		self.to_float().asin().into()
406	}
407
408	pub fn atan(self) -> Self {
409		self.to_float().atan().into()
410	}
411
412	pub fn acot(self) -> Self {
413		(PI / 2.0 - self.atan().to_float()).into()
414	}
415
416	pub fn ceil(self) -> Self {
417		match self {
418			Number::Int(v) => v.into(),
419			Number::Float(v) => v.ceil().into(),
420			Number::Decimal(v) => v.ceil().into(),
421		}
422	}
423
424	pub fn clamp(self, min: Self, max: Self) -> Self {
425		match (self, min, max) {
426			(Number::Int(n), Number::Int(min), Number::Int(max)) => n.clamp(min, max).into(),
427			(Number::Decimal(n), min, max) => n.clamp(min.to_decimal(), max.to_decimal()).into(),
428			(Number::Float(n), min, max) => n.clamp(min.to_float(), max.to_float()).into(),
429			(Number::Int(n), min, max) => n.to_float().clamp(min.to_float(), max.to_float()).into(),
430		}
431	}
432
433	pub fn cos(self) -> Self {
434		self.to_float().cos().into()
435	}
436
437	pub fn cot(self) -> Self {
438		(1.0 / self.to_float().tan()).into()
439	}
440
441	pub fn deg2rad(self) -> Self {
442		self.to_float().to_radians().into()
443	}
444
445	pub fn floor(self) -> Self {
446		match self {
447			Number::Int(v) => v.into(),
448			Number::Float(v) => v.floor().into(),
449			Number::Decimal(v) => v.floor().into(),
450		}
451	}
452
453	fn lerp_f64(from: f64, to: f64, factor: f64) -> f64 {
454		from + factor * (to - from)
455	}
456
457	fn lerp_decimal(from: Decimal, to: Decimal, factor: Decimal) -> Decimal {
458		from + factor * (to - from)
459	}
460
461	pub fn lerp(self, from: Self, to: Self) -> Self {
462		match (self, from, to) {
463			(Number::Decimal(val), from, to) => {
464				Self::lerp_decimal(from.to_decimal(), to.to_decimal(), val).into()
465			}
466			(val, from, to) => {
467				Self::lerp_f64(from.to_float(), to.to_float(), val.to_float()).into()
468			}
469		}
470	}
471
472	fn repeat_f64(t: f64, m: f64) -> f64 {
473		(t - (t / m).floor() * m).clamp(0.0, m)
474	}
475
476	fn repeat_decimal(t: Decimal, m: Decimal) -> Decimal {
477		(t - (t / m).floor() * m).clamp(Decimal::ZERO, m)
478	}
479
480	pub fn lerp_angle(self, from: Self, to: Self) -> Self {
481		match (self, from, to) {
482			(Number::Decimal(val), from, to) => {
483				let from = from.to_decimal();
484				let to = to.to_decimal();
485				let mut dt = Self::repeat_decimal(to - from, Decimal::from(360));
486				if dt > Decimal::from(180) {
487					dt = Decimal::from(360) - dt;
488				}
489				Self::lerp_decimal(from, from + dt, val).into()
490			}
491			(val, from, to) => {
492				let val = val.to_float();
493				let from = from.to_float();
494				let to = to.to_float();
495				let mut dt = Self::repeat_f64(to - from, 360.0);
496				if dt > 180.0 {
497					dt = 360.0 - dt;
498				}
499				Self::lerp_f64(from, from + dt, val).into()
500			}
501		}
502	}
503
504	pub fn ln(self) -> Self {
505		self.to_float().ln().into()
506	}
507
508	pub fn log(self, base: Self) -> Self {
509		self.to_float().log(base.to_float()).into()
510	}
511
512	pub fn log2(self) -> Self {
513		self.to_float().log2().into()
514	}
515
516	pub fn log10(self) -> Self {
517		self.to_float().log10().into()
518	}
519
520	pub fn rad2deg(self) -> Self {
521		self.to_float().to_degrees().into()
522	}
523
524	pub fn round(self) -> Self {
525		match self {
526			Number::Int(v) => v.into(),
527			Number::Float(v) => v.round().into(),
528			Number::Decimal(v) => v.round().into(),
529		}
530	}
531
532	pub fn fixed(self, precision: usize) -> Number {
533		match self {
534			Number::Int(v) => format!("{v:.precision$}").try_into().unwrap_or_default(),
535			Number::Float(v) => format!("{v:.precision$}").try_into().unwrap_or_default(),
536			Number::Decimal(v) => v.round_dp(precision as u32).into(),
537		}
538	}
539
540	pub fn sign(self) -> Self {
541		match self {
542			Number::Int(n) => n.signum().into(),
543			Number::Float(n) => n.signum().into(),
544			Number::Decimal(n) => n.signum().into(),
545		}
546	}
547
548	pub fn sin(self) -> Self {
549		self.to_float().sin().into()
550	}
551
552	pub fn tan(self) -> Self {
553		self.to_float().tan().into()
554	}
555
556	pub fn sqrt(self) -> Self {
557		match self {
558			Number::Int(v) => (v as f64).sqrt().into(),
559			Number::Float(v) => v.sqrt().into(),
560			Number::Decimal(v) => v.sqrt().unwrap_or_default().into(),
561		}
562	}
563
564	pub fn pow(self, power: Number) -> Number {
565		match (self, power) {
566			(Number::Int(v), Number::Int(p)) => Number::Int(v.pow(p as u32)),
567			(Number::Decimal(v), Number::Int(p)) => v.powi(p).into(),
568			// TODO: (Number::Decimal(v), Number::Float(p)) => todo!(),
569			// TODO: (Number::Decimal(v), Number::Decimal(p)) => todo!(),
570			(v, p) => v.as_float().powf(p.as_float()).into(),
571		}
572	}
573}
574
575impl Eq for Number {}
576
577impl Ord for Number {
578	fn cmp(&self, other: &Self) -> Ordering {
579		fn total_cmp_f64(a: f64, b: f64) -> Ordering {
580			if a == 0.0 && b == 0.0 {
581				// -0.0 = 0.0
582				Ordering::Equal
583			} else {
584				// Handles NaN's
585				a.total_cmp(&b)
586			}
587		}
588
589		// Pick the greater number depending on whether it's positive.
590		macro_rules! greater {
591			($f:ident) => {
592				if $f.is_sign_positive() {
593					Ordering::Greater
594				} else {
595					Ordering::Less
596				}
597			};
598		}
599
600		match (self, other) {
601			(Number::Int(v), Number::Int(w)) => v.cmp(w),
602			(Number::Float(v), Number::Float(w)) => total_cmp_f64(*v, *w),
603			(Number::Decimal(v), Number::Decimal(w)) => v.cmp(w),
604			// ------------------------------
605			(Number::Int(v), Number::Float(w)) => {
606				// If the float is not finite, we don't need to compare it to the integer.
607				if !w.is_finite() {
608					return greater!(w).reverse();
609				}
610				// Cast int to i128 to avoid saturating.
611				let l = *v as i128;
612				// Cast the integer-part of the float to i128 to avoid saturating.
613				let r = *w as i128;
614				// Compare both integer parts.
615				match l.cmp(&r) {
616					// If the integer parts are equal then we need to compare the mantissa.
617					Ordering::Equal => total_cmp_f64(0.0, w.fract()),
618					// If the integer parts are not equal then we already know the correct ordering.
619					ordering => ordering,
620				}
621			}
622			(v @ Number::Float(_), w @ Number::Int(_)) => w.cmp(v).reverse(),
623			// ------------------------------
624			(Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).cmp(w),
625			(Number::Decimal(v), Number::Int(w)) => v.cmp(&Decimal::from(*w)),
626			// ------------------------------
627			(Number::Float(v), Number::Decimal(w)) => {
628				// Compare fractional parts of the float and decimal.
629				macro_rules! compare_fractions {
630					($l:ident, $r:ident) => {
631						match ($l == 0.0, $r == Decimal::ZERO) {
632							// If both numbers are zero, these are equal.
633							(true, true) => {
634								return Ordering::Equal;
635							}
636							// If only the float is zero, check the decimal's sign.
637							(true, false) => {
638								return greater!($r).reverse();
639							}
640							// If only the decimal is zero, check the float's sign.
641							(false, true) => {
642								return greater!($l);
643							}
644							// If neither is zero, continue checking the rest of the digits.
645							(false, false) => {
646								continue;
647							}
648						}
649					};
650				}
651				// If the float is not finite, we don't need to compare it to the decimal
652				if !v.is_finite() {
653					return greater!(v);
654				}
655				// Cast int to i128 to avoid saturating.
656				let l = *v as i128;
657				// Cast the integer-part of the decimal to i128.
658				let Ok(r) = i128::try_from(*w) else {
659					return greater!(w).reverse();
660				};
661				// Compare both integer parts.
662				match l.cmp(&r) {
663					// If the integer parts are equal then we need to compare the fractional parts.
664					Ordering::Equal => {
665						// We can't compare the fractional parts of floats with decimals reliably.
666						// Instead, we need to compare them as integers. To do this, we need to
667						// multiply the fraction with a number large enough to move some digits
668						// to the integer part of the float or decimal. The number should fit in
669						// 52 bits and be able to multiply f64 fractions between -1 and 1 without
670						// losing precision. Since we may need to do this repeatedly it helps if
671						// the number is as big as possible to reduce the number of
672						// iterations needed.
673						//
674						// This number is roughly 2 ^ 53 with the last digits truncated in order
675						// to make sure the fraction converges to 0 every time we multiply it.
676						// This is a magic number I found through my experiments so don't ask me
677						// the logic behind it :) Before changing this number, please make sure
678						// that the relevant tests aren't flaky after changing it.
679						const SAFE_MULTIPLIER: i64 = 9_007_199_254_740_000;
680						// Get the fractional part of the float.
681						let mut l = v.fract();
682						// Get the fractional part of the decimal.
683						let mut r = w.fract();
684						// Move the digits and compare them.
685						// This is very generous. For example, for our tests to pass we only need
686						// 3 iterations. This should be at least 6 to make sure we cover all
687						// possible decimals and floats.
688						for _ in 0..12 {
689							l *= SAFE_MULTIPLIER as f64;
690							r *= Decimal::new(SAFE_MULTIPLIER, 0);
691							// Cast the integer part of the decimal to i64. The fractions are always
692							// less than 1 so we know this will always be less than SAFE_MULTIPLIER.
693							match r.to_i64() {
694								Some(ref right) => match (l as i64).cmp(right) {
695									// If the integer parts are equal, we need to check the remaining
696									// fractional parts.
697									Ordering::Equal => {
698										// Drop the integer parts we already compared.
699										l = l.fract();
700										r = r.fract();
701										// Compare the fractional parts and decide whether to return
702										// or continue checking the next digits.
703										compare_fractions!(l, r);
704									}
705									ordering => {
706										// If the integer parts are not equal then we already know the
707										// correct ordering.
708										return ordering;
709									}
710								},
711								// This is technically unreachable. Reaching this part likely indicates
712								// a bug in `rust-decimal`'s `to_f64`'s implementation.
713								None => {
714									// We will assume the decimal is bigger or smaller depending on its
715									// sign.
716									return greater!(w).reverse();
717								}
718							}
719						}
720						// After our iterations, if we still haven't exhausted both fractions we will
721						// just treat them as equal. It should be impossible to reach this point after
722						// at least 6 iterations. We could use an infinite loop instead but this way
723						// we make sure the loop always exits.
724						Ordering::Equal
725					}
726					// If the integer parts are not equal then we already know the correct ordering.
727					ordering => ordering,
728				}
729			}
730			(v @ Number::Decimal(..), w @ Number::Float(..)) => w.cmp(v).reverse(),
731		}
732	}
733}
734
735// Warning: Equal numbers may have different hashes, which violates
736// the invariants of certain collections!
737impl hash::Hash for Number {
738	fn hash<H: hash::Hasher>(&self, state: &mut H) {
739		match self {
740			Number::Int(v) => v.hash(state),
741			Number::Float(v) => v.to_bits().hash(state),
742			Number::Decimal(v) => v.hash(state),
743		}
744	}
745}
746
747impl PartialEq for Number {
748	fn eq(&self, other: &Self) -> bool {
749		fn total_eq_f64(a: f64, b: f64) -> bool {
750			a.to_bits().eq(&b.to_bits()) || (a == 0.0 && b == 0.0)
751		}
752
753		match (self, other) {
754			(Number::Int(v), Number::Int(w)) => v.eq(w),
755			(Number::Float(v), Number::Float(w)) => total_eq_f64(*v, *w),
756			(Number::Decimal(v), Number::Decimal(w)) => v.eq(w),
757			// ------------------------------
758			(v @ Number::Int(_), w @ Number::Float(_)) => v.cmp(w) == Ordering::Equal,
759			(v @ Number::Float(_), w @ Number::Int(_)) => v.cmp(w) == Ordering::Equal,
760			// ------------------------------
761			(Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).eq(w),
762			(Number::Decimal(v), Number::Int(w)) => v.eq(&Decimal::from(*w)),
763			// ------------------------------
764			(v @ Number::Float(_), w @ Number::Decimal(_)) => v.cmp(w) == Ordering::Equal,
765			(v @ Number::Decimal(_), w @ Number::Float(_)) => v.cmp(w) == Ordering::Equal,
766		}
767	}
768}
769
770impl PartialOrd for Number {
771	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
772		Some(self.cmp(other))
773	}
774}
775
776macro_rules! impl_simple_try_op {
777	($trt:ident, $fn:ident, $unchecked:ident, $checked:ident) => {
778		impl $trt for Number {
779			type Output = Self;
780			fn $fn(self, other: Self) -> Result<Self, Error> {
781				Ok(match (self, other) {
782					(Number::Int(v), Number::Int(w)) => Number::Int(
783						v.$checked(w).ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
784					),
785					(Number::Float(v), Number::Float(w)) => Number::Float(v.$unchecked(w)),
786					(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(
787						v.$checked(w).ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
788					),
789					(Number::Int(v), Number::Float(w)) => Number::Float((v as f64).$unchecked(w)),
790					(Number::Float(v), Number::Int(w)) => Number::Float(v.$unchecked(w as f64)),
791					(v, w) => Number::Decimal(
792						v.to_decimal()
793							.$checked(w.to_decimal())
794							.ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
795					),
796				})
797			}
798		}
799	};
800}
801
802impl_simple_try_op!(TryAdd, try_add, add, checked_add);
803impl_simple_try_op!(TrySub, try_sub, sub, checked_sub);
804impl_simple_try_op!(TryMul, try_mul, mul, checked_mul);
805impl_simple_try_op!(TryDiv, try_div, div, checked_div);
806impl_simple_try_op!(TryRem, try_rem, rem, checked_rem);
807
808impl TryPow for Number {
809	type Output = Self;
810	fn try_pow(self, power: Self) -> Result<Self, Error> {
811		Ok(match (self, power) {
812			(Self::Int(v), Self::Int(p)) => Self::Int(match v {
813				0 => match p.cmp(&0) {
814					// 0^(-x)
815					Ordering::Less => return Err(Error::TryPow(v.to_string(), p.to_string())),
816					// 0^0
817					Ordering::Equal => 1,
818					// 0^x
819					Ordering::Greater => 0,
820				},
821				// 1^p
822				1 => 1,
823				-1 => {
824					if p % 2 == 0 {
825						// (-1)^even
826						1
827					} else {
828						// (-1)^odd
829						-1
830					}
831				}
832				// try_into may cause an error, which would be wrong for the above cases.
833				_ => p
834					.try_into()
835					.ok()
836					.and_then(|p| v.checked_pow(p))
837					.ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
838			}),
839			(Self::Decimal(v), Self::Int(p)) => Self::Decimal(
840				v.checked_powi(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
841			),
842			(Self::Decimal(v), Self::Float(p)) => Self::Decimal(
843				v.checked_powf(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
844			),
845			(Self::Decimal(v), Self::Decimal(p)) => Self::Decimal(
846				v.checked_powd(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
847			),
848			(v, p) => v.as_float().powf(p.as_float()).into(),
849		})
850	}
851}
852
853impl TryNeg for Number {
854	type Output = Self;
855
856	fn try_neg(self) -> Result<Self::Output, Error> {
857		Ok(match self {
858			Self::Int(n) => {
859				Number::Int(n.checked_neg().ok_or_else(|| Error::TryNeg(n.to_string()))?)
860			}
861			Self::Float(n) => Number::Float(-n),
862			Self::Decimal(n) => Number::Decimal(-n),
863		})
864	}
865}
866
867impl TryFloatDiv for Number {
868	type Output = Self;
869	fn try_float_div(self, other: Self) -> Result<Self, Error> {
870		Ok(match (self, other) {
871			(Number::Int(v), Number::Int(w)) => {
872				let quotient = (v as f64).div(w as f64);
873				if quotient.fract() != 0.0 {
874					return Ok(Number::Float(quotient));
875				}
876				Number::Int(
877					v.checked_div(w).ok_or_else(|| Error::TryDiv(v.to_string(), w.to_string()))?,
878				)
879			}
880			(v, w) => v.try_div(w)?,
881		})
882	}
883}
884
885impl ops::Add for Number {
886	type Output = Self;
887	fn add(self, other: Self) -> Self {
888		match (self, other) {
889			(Number::Int(v), Number::Int(w)) => Number::Int(v + w),
890			(Number::Float(v), Number::Float(w)) => Number::Float(v + w),
891			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v + w),
892			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 + w),
893			(Number::Float(v), Number::Int(w)) => Number::Float(v + w as f64),
894			(v, w) => Number::from(v.as_decimal() + w.as_decimal()),
895		}
896	}
897}
898
899impl<'b> ops::Add<&'b Number> for &Number {
900	type Output = Number;
901	fn add(self, other: &'b Number) -> Number {
902		match (self, other) {
903			(Number::Int(v), Number::Int(w)) => Number::Int(v + w),
904			(Number::Float(v), Number::Float(w)) => Number::Float(v + w),
905			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v + w),
906			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 + w),
907			(Number::Float(v), Number::Int(w)) => Number::Float(v + *w as f64),
908			(v, w) => Number::from(v.to_decimal() + w.to_decimal()),
909		}
910	}
911}
912
913impl ops::Sub for Number {
914	type Output = Self;
915	fn sub(self, other: Self) -> Self {
916		match (self, other) {
917			(Number::Int(v), Number::Int(w)) => Number::Int(v - w),
918			(Number::Float(v), Number::Float(w)) => Number::Float(v - w),
919			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v - w),
920			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 - w),
921			(Number::Float(v), Number::Int(w)) => Number::Float(v - w as f64),
922			(v, w) => Number::from(v.as_decimal() - w.as_decimal()),
923		}
924	}
925}
926
927impl<'b> ops::Sub<&'b Number> for &Number {
928	type Output = Number;
929	fn sub(self, other: &'b Number) -> Number {
930		match (self, other) {
931			(Number::Int(v), Number::Int(w)) => Number::Int(v - w),
932			(Number::Float(v), Number::Float(w)) => Number::Float(v - w),
933			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v - w),
934			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 - w),
935			(Number::Float(v), Number::Int(w)) => Number::Float(v - *w as f64),
936			(v, w) => Number::from(v.to_decimal() - w.to_decimal()),
937		}
938	}
939}
940
941impl ops::Mul for Number {
942	type Output = Self;
943	fn mul(self, other: Self) -> Self {
944		match (self, other) {
945			(Number::Int(v), Number::Int(w)) => Number::Int(v * w),
946			(Number::Float(v), Number::Float(w)) => Number::Float(v * w),
947			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v * w),
948			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 * w),
949			(Number::Float(v), Number::Int(w)) => Number::Float(v * w as f64),
950			(v, w) => Number::from(v.as_decimal() * w.as_decimal()),
951		}
952	}
953}
954
955impl<'b> ops::Mul<&'b Number> for &Number {
956	type Output = Number;
957	fn mul(self, other: &'b Number) -> Number {
958		match (self, other) {
959			(Number::Int(v), Number::Int(w)) => Number::Int(v * w),
960			(Number::Float(v), Number::Float(w)) => Number::Float(v * w),
961			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v * w),
962			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 * w),
963			(Number::Float(v), Number::Int(w)) => Number::Float(v * *w as f64),
964			(v, w) => Number::from(v.to_decimal() * w.to_decimal()),
965		}
966	}
967}
968
969impl ops::Div for Number {
970	type Output = Self;
971	fn div(self, other: Self) -> Self {
972		match (self, other) {
973			(Number::Int(v), Number::Int(w)) => Number::Int(v / w),
974			(Number::Float(v), Number::Float(w)) => Number::Float(v / w),
975			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v / w),
976			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 / w),
977			(Number::Float(v), Number::Int(w)) => Number::Float(v / w as f64),
978			(v, w) => Number::from(v.as_decimal() / w.as_decimal()),
979		}
980	}
981}
982
983impl<'b> ops::Div<&'b Number> for &Number {
984	type Output = Number;
985	fn div(self, other: &'b Number) -> Number {
986		match (self, other) {
987			(Number::Int(v), Number::Int(w)) => Number::Int(v / w),
988			(Number::Float(v), Number::Float(w)) => Number::Float(v / w),
989			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v / w),
990			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 / w),
991			(Number::Float(v), Number::Int(w)) => Number::Float(v / *w as f64),
992			(v, w) => Number::from(v.to_decimal() / w.to_decimal()),
993		}
994	}
995}
996
997impl Neg for Number {
998	type Output = Self;
999
1000	fn neg(self) -> Self::Output {
1001		match self {
1002			Self::Int(n) => Number::Int(-n),
1003			Self::Float(n) => Number::Float(-n),
1004			Self::Decimal(n) => Number::Decimal(-n),
1005		}
1006	}
1007}
1008
1009// ------------------------------
1010
1011impl Sum<Self> for Number {
1012	fn sum<I>(iter: I) -> Number
1013	where
1014		I: Iterator<Item = Self>,
1015	{
1016		iter.fold(Number::Int(0), |a, b| a + b)
1017	}
1018}
1019
1020impl<'a> Sum<&'a Self> for Number {
1021	fn sum<I>(iter: I) -> Number
1022	where
1023		I: Iterator<Item = &'a Self>,
1024	{
1025		iter.fold(Number::Int(0), |a, b| &a + b)
1026	}
1027}
1028
1029impl Product<Self> for Number {
1030	fn product<I>(iter: I) -> Number
1031	where
1032		I: Iterator<Item = Self>,
1033	{
1034		iter.fold(Number::Int(1), |a, b| a * b)
1035	}
1036}
1037
1038impl<'a> Product<&'a Self> for Number {
1039	fn product<I>(iter: I) -> Number
1040	where
1041		I: Iterator<Item = &'a Self>,
1042	{
1043		iter.fold(Number::Int(1), |a, b| &a * b)
1044	}
1045}
1046
1047#[non_exhaustive]
1048pub struct Sorted<T>(pub T);
1049
1050pub trait Sort {
1051	fn sorted(&mut self) -> Sorted<&Self>
1052	where
1053		Self: Sized;
1054}
1055
1056impl Sort for Vec<Number> {
1057	fn sorted(&mut self) -> Sorted<&Vec<Number>> {
1058		self.sort();
1059		Sorted(self)
1060	}
1061}
1062
1063impl ToFloat for Number {
1064	fn to_float(&self) -> f64 {
1065		self.to_float()
1066	}
1067}
1068
1069#[cfg(test)]
1070mod tests {
1071	use std::cmp::Ordering;
1072
1073	use rand::seq::SliceRandom;
1074	use rand::thread_rng;
1075	use rand::Rng;
1076	use rust_decimal::Decimal;
1077
1078	use super::Number;
1079	use super::TryFloatDiv;
1080	#[test]
1081	fn test_try_float_div() {
1082		let (sum_one, count_one) = (Number::Int(5), Number::Int(2));
1083		assert_eq!(sum_one.try_float_div(count_one).unwrap(), Number::Float(2.5));
1084		// i64::MIN
1085
1086		let (sum_two, count_two) = (Number::Int(10), Number::Int(5));
1087		assert_eq!(sum_two.try_float_div(count_two).unwrap(), Number::Int(2));
1088
1089		let (sum_three, count_three) = (Number::Float(6.3), Number::Int(3));
1090		assert_eq!(sum_three.try_float_div(count_three).unwrap(), Number::Float(2.1));
1091	}
1092
1093	#[test]
1094	fn ord_test() {
1095		let a = Number::Float(-f64::NAN);
1096		let b = Number::Float(-f64::INFINITY);
1097		let c = Number::Float(1f64);
1098		let d = Number::Decimal(Decimal::from_str_exact("1.0000000000000000000000000002").unwrap());
1099		let e = Number::Decimal(Decimal::from_str_exact("1.1").unwrap());
1100		let f = Number::Float(1.1f64);
1101		let g = Number::Float(1.5f64);
1102		let h = Number::Decimal(Decimal::from_str_exact("1.5").unwrap());
1103		let i = Number::Float(f64::INFINITY);
1104		let j = Number::Float(f64::NAN);
1105		let original = vec![a, b, c, d, e, f, g, h, i, j];
1106		let mut copy = original.clone();
1107		let mut rng = thread_rng();
1108		copy.shuffle(&mut rng);
1109		copy.sort();
1110		assert_eq!(original, copy);
1111	}
1112
1113	#[test]
1114	fn ord_fuzz() {
1115		fn random_number() -> Number {
1116			let mut rng = thread_rng();
1117			match rng.gen_range(0..3) {
1118				0 => Number::Int(rng.gen()),
1119				1 => Number::Float(f64::from_bits(rng.gen())),
1120				_ => Number::Decimal(Number::Float(f64::from_bits(rng.gen())).as_decimal()),
1121			}
1122		}
1123
1124		// TODO: Use std library once stable https://doc.rust-lang.org/std/primitive.f64.html#method.next_down
1125		fn next_down(n: f64) -> f64 {
1126			const TINY_BITS: u64 = 0x1; // Smallest positive f64.
1127			const CLEAR_SIGN_MASK: u64 = 0x7fff_ffff_ffff_ffff;
1128
1129			let bits = n.to_bits();
1130			if n.is_nan() || bits == f64::INFINITY.to_bits() {
1131				return n;
1132			}
1133
1134			let abs = bits & CLEAR_SIGN_MASK;
1135			let next_bits = if abs == 0 {
1136				TINY_BITS
1137			} else if bits == abs {
1138				bits + 1
1139			} else {
1140				bits - 1
1141			};
1142			f64::from_bits(next_bits)
1143		}
1144
1145		fn random_permutation(number: Number) -> Number {
1146			let mut rng = thread_rng();
1147			let value = match rng.gen_range(0..4) {
1148				0 => number + Number::from(rng.gen::<f64>()),
1149				1 if !matches!(number, Number::Int(i64::MIN)) => number * Number::from(-1),
1150				2 => Number::Float(next_down(number.as_float())),
1151				_ => number,
1152			};
1153			match rng.gen_range(0..3) {
1154				0 => Number::Int(value.as_int()),
1155				1 => Number::Float(value.as_float()),
1156				_ => Number::Decimal(value.as_decimal()),
1157			}
1158		}
1159
1160		fn assert_partial_ord(x: Number, y: Number) {
1161			// PartialOrd requirements
1162			assert_eq!(x == y, x.partial_cmp(&y) == Some(Ordering::Equal), "{x:?} {y:?}");
1163
1164			// Ord consistent with PartialOrd
1165			assert_eq!(x.partial_cmp(&y), Some(x.cmp(&y)), "{x:?} {y:?}");
1166		}
1167
1168		fn assert_consistent(a: Number, b: Number, c: Number) {
1169			assert_partial_ord(a, b);
1170			assert_partial_ord(b, c);
1171			assert_partial_ord(c, a);
1172
1173			// Transitive property (without the fix, these can fail)
1174			if a == b && b == c {
1175				assert_eq!(a, c, "{a:?} {b:?} {c:?}");
1176			}
1177			if a != b && b == c {
1178				assert_ne!(a, c, "{a:?} {b:?} {c:?}");
1179			}
1180			if a < b && b < c {
1181				assert!(a < c, "{a:?} {b:?} {c:?}");
1182			}
1183			if a > b && b > c {
1184				assert!(a > c, "{a:?} {b:?} {c:?}");
1185			}
1186
1187			// Duality
1188			assert_eq!(a == b, b == a, "{a:?} {b:?}");
1189			assert_eq!(a < b, b > a, "{a:?} {b:?}");
1190		}
1191
1192		for _ in 0..100000 {
1193			let base = random_number();
1194			let a = random_permutation(base);
1195			let b = random_permutation(a);
1196			let c = random_permutation(b);
1197			assert_consistent(a, b, c);
1198		}
1199	}
1200}