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 }
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 match v.parse::<i64>() {
96 Ok(v) => Ok(Self::Int(v)),
98 _ => match f64::from_str(v) {
100 Ok(v) => Ok(Self::Float(v)),
102 _ => Err(()),
104 },
105 }
106 }
107}
108
109macro_rules! try_into_prim {
110 ($($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 write!(f, "{v}f")
215 } else {
216 Display::fmt(v, f)
218 }
219 }
220 Number::Decimal(v) => write!(f, "{v}dec"),
221 }
222 }
223}
224
225impl Number {
226 pub const NAN: Number = Number::Float(f64::NAN);
231
232 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 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 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 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 (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 Ordering::Equal
575 } else {
576 a.total_cmp(&b)
578 }
579 }
580
581 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 (Number::Int(v), Number::Float(w)) => {
598 if !w.is_finite() {
600 return greater!(w).reverse();
601 }
602 let l = *v as i128;
604 let r = *w as i128;
606 match l.cmp(&r) {
608 Ordering::Equal => total_cmp_f64(0.0, w.fract()),
610 ordering => ordering,
612 }
613 }
614 (v @ Number::Float(_), w @ Number::Int(_)) => w.cmp(v).reverse(),
615 (Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).cmp(w),
617 (Number::Decimal(v), Number::Int(w)) => v.cmp(&Decimal::from(*w)),
618 (Number::Float(v), Number::Decimal(w)) => {
620 macro_rules! compare_fractions {
622 ($l:ident, $r:ident) => {
623 match ($l == 0.0, $r == Decimal::ZERO) {
624 (true, true) => {
626 return Ordering::Equal;
627 }
628 (true, false) => {
630 return greater!($r).reverse();
631 }
632 (false, true) => {
634 return greater!($l);
635 }
636 (false, false) => {
638 continue;
639 }
640 }
641 };
642 }
643 if !v.is_finite() {
645 return greater!(v);
646 }
647 let l = *v as i128;
649 let Ok(r) = i128::try_from(*w) else {
651 return greater!(w).reverse();
652 };
653 match l.cmp(&r) {
655 Ordering::Equal => {
657 const SAFE_MULTIPLIER: i64 = 9_007_199_254_740_000;
672 let mut l = v.fract();
674 let mut r = w.fract();
676 for _ in 0..12 {
681 l *= SAFE_MULTIPLIER as f64;
682 r *= Decimal::new(SAFE_MULTIPLIER, 0);
683 match r.to_i64() {
686 Some(ref right) => match (l as i64).cmp(right) {
687 Ordering::Equal => {
690 l = l.fract();
692 r = r.fract();
693 compare_fractions!(l, r);
696 }
697 ordering => {
698 return ordering;
701 }
702 },
703 None => {
706 return greater!(w).reverse();
709 }
710 }
711 }
712 Ordering::Equal
717 }
718 ordering => ordering,
720 }
721 }
722 (v @ Number::Decimal(..), w @ Number::Float(..)) => w.cmp(v).reverse(),
723 }
724 }
725}
726
727impl 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 (v @ Number::Int(_), w @ Number::Float(_)) => v.cmp(w) == Ordering::Equal,
751 (v @ Number::Float(_), w @ Number::Int(_)) => v.cmp(w) == Ordering::Equal,
752 (Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).eq(w),
754 (Number::Decimal(v), Number::Int(w)) => v.eq(&Decimal::from(*w)),
755 (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 Ordering::Less => return Err(Error::TryPow(v.to_string(), p.to_string())),
808 Ordering::Equal => 1,
810 Ordering::Greater => 0,
812 },
813 1 => 1,
815 -1 => {
816 if p % 2 == 0 {
817 1
819 } else {
820 -1
822 }
823 }
824 _ => 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
1001impl 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 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 fn next_down(n: f64) -> f64 {
1118 const TINY_BITS: u64 = 0x1; 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 assert_eq!(x == y, x.partial_cmp(&y) == Some(Ordering::Equal), "{x:?} {y:?}");
1155
1156 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 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 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}