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 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 (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 Ordering::Equal
583 } else {
584 a.total_cmp(&b)
586 }
587 }
588
589 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 (Number::Int(v), Number::Float(w)) => {
606 if !w.is_finite() {
608 return greater!(w).reverse();
609 }
610 let l = *v as i128;
612 let r = *w as i128;
614 match l.cmp(&r) {
616 Ordering::Equal => total_cmp_f64(0.0, w.fract()),
618 ordering => ordering,
620 }
621 }
622 (v @ Number::Float(_), w @ Number::Int(_)) => w.cmp(v).reverse(),
623 (Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).cmp(w),
625 (Number::Decimal(v), Number::Int(w)) => v.cmp(&Decimal::from(*w)),
626 (Number::Float(v), Number::Decimal(w)) => {
628 macro_rules! compare_fractions {
630 ($l:ident, $r:ident) => {
631 match ($l == 0.0, $r == Decimal::ZERO) {
632 (true, true) => {
634 return Ordering::Equal;
635 }
636 (true, false) => {
638 return greater!($r).reverse();
639 }
640 (false, true) => {
642 return greater!($l);
643 }
644 (false, false) => {
646 continue;
647 }
648 }
649 };
650 }
651 if !v.is_finite() {
653 return greater!(v);
654 }
655 let l = *v as i128;
657 let Ok(r) = i128::try_from(*w) else {
659 return greater!(w).reverse();
660 };
661 match l.cmp(&r) {
663 Ordering::Equal => {
665 const SAFE_MULTIPLIER: i64 = 9_007_199_254_740_000;
680 let mut l = v.fract();
682 let mut r = w.fract();
684 for _ in 0..12 {
689 l *= SAFE_MULTIPLIER as f64;
690 r *= Decimal::new(SAFE_MULTIPLIER, 0);
691 match r.to_i64() {
694 Some(ref right) => match (l as i64).cmp(right) {
695 Ordering::Equal => {
698 l = l.fract();
700 r = r.fract();
701 compare_fractions!(l, r);
704 }
705 ordering => {
706 return ordering;
709 }
710 },
711 None => {
714 return greater!(w).reverse();
717 }
718 }
719 }
720 Ordering::Equal
725 }
726 ordering => ordering,
728 }
729 }
730 (v @ Number::Decimal(..), w @ Number::Float(..)) => w.cmp(v).reverse(),
731 }
732 }
733}
734
735impl 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 (v @ Number::Int(_), w @ Number::Float(_)) => v.cmp(w) == Ordering::Equal,
759 (v @ Number::Float(_), w @ Number::Int(_)) => v.cmp(w) == Ordering::Equal,
760 (Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).eq(w),
762 (Number::Decimal(v), Number::Int(w)) => v.eq(&Decimal::from(*w)),
763 (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 Ordering::Less => return Err(Error::TryPow(v.to_string(), p.to_string())),
816 Ordering::Equal => 1,
818 Ordering::Greater => 0,
820 },
821 1 => 1,
823 -1 => {
824 if p % 2 == 0 {
825 1
827 } else {
828 -1
830 }
831 }
832 _ => 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
1009impl 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 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 fn next_down(n: f64) -> f64 {
1126 const TINY_BITS: u64 = 0x1; 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 assert_eq!(x == y, x.partial_cmp(&y) == Some(Ordering::Equal), "{x:?} {y:?}");
1163
1164 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 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 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}