1use super::{NewDeciVal, Parse, Prec, SinhCosh, SpecialValuesDeci};
2use crate::macros::impls::{
3 dec_impl, impl_neg, impl_new_val_deci, impl_partial_ord, impl_rem, impl_self_ops,
4};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7use std::cmp::Ordering;
8use std::fmt::{Display, Formatter};
9use std::ops::{Div, Mul};
10#[derive(Copy, Clone, PartialEq)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum Decimal {
13 D512(fastnum::D512),
14 D256(fastnum::D256),
15}
16
17impl Prec for Decimal {
18 fn prec(&self) -> u32 {
19 match self {
20 Self::D512(_) => 512,
21 Self::D256(_) => 256,
22 }
23 }
24 fn set_prec(&mut self, _new_prec: u32) {
25 match self {
26 Self::D512(_) => todo!(),
27 Self::D256(_) => todo!(),
28 }
29 }
30}
31
32impl Decimal {
33 pub fn is_zero(&self) -> bool {
34 match self {
35 Self::D512(a) => a.is_zero(),
36 Self::D256(a) => a.is_zero(),
37 }
38 }
39 pub fn to_integer(self) -> fastnum::I512 {
40 match self {
41 Self::D512(_) => todo!(),
42 Self::D256(_) => todo!(),
43 }
44 }
45 pub fn to_f64(&self) -> f64 {
46 match self {
47 Self::D512(_) => todo!(),
48 Self::D256(_) => todo!(),
49 }
50 }
51 pub fn to_string_radix(self, _base: i32, _num_digits: Option<usize>) -> String {
52 match self {
53 Self::D512(a) => a.to_string(),
54 Self::D256(a) => a.to_string(),
55 }
56 }
57}
58
59impl Mul<fastnum::I512> for Decimal {
60 type Output = Self;
61 fn mul(self, rhs: fastnum::I512) -> Self::Output {
62 match self {
63 Decimal::D512(a) => Decimal::D512(
64 a * fastnum::D512::from_str(&rhs.to_string(), fastnum::decimal::Context::default())
65 .unwrap_or_default(),
66 ),
67 Decimal::D256(a) => Decimal::D256(
68 a * fastnum::D256::from_str(&rhs.to_string(), fastnum::decimal::Context::default())
69 .unwrap_or_default(),
70 ),
71 }
72 }
73}
74
75impl Div<fastnum::I512> for Decimal {
76 type Output = Self;
77 fn div(self, rhs: fastnum::I512) -> Self::Output {
78 match self {
79 Decimal::D512(a) => Decimal::D512(
80 a / fastnum::D512::from_str(&rhs.to_string(), fastnum::decimal::Context::default())
81 .unwrap_or_default(),
82 ),
83 Decimal::D256(a) => Decimal::D256(
84 a / fastnum::D256::from_str(&rhs.to_string(), fastnum::decimal::Context::default())
85 .unwrap_or_default(),
86 ),
87 }
88 }
89}
90
91impl Parse<&str> for Decimal {
92 fn parse(prec: u32, s: &str) -> Option<Self> {
93 match prec.next_power_of_two() {
94 512 => fastnum::D512::from_str(s, fastnum::decimal::Context::default())
95 .ok()
96 .map(Self::D512),
97 256 => fastnum::D256::from_str(s, fastnum::decimal::Context::default())
98 .ok()
99 .map(Self::D256),
100 _ => unreachable!(),
101 }
102 }
103 fn parse_radix(prec: u32, s: &str, _base: i32) -> Option<Self> {
104 match prec.next_power_of_two() {
105 512 => fastnum::D512::from_str(s, fastnum::decimal::Context::default())
106 .ok()
107 .map(Self::D512),
108 256 => fastnum::D256::from_str(s, fastnum::decimal::Context::default())
109 .ok()
110 .map(Self::D256),
111 _ => unreachable!(),
112 }
113 }
114}
115
116impl SpecialValuesDeci for Decimal {
117 fn pi(prec: u32) -> Self {
118 match prec.next_power_of_two() {
119 512 => Self::D512(fastnum::D512::PI),
120 256 => Self::D256(fastnum::D256::PI),
121 _ => unreachable!(),
122 }
123 }
124 fn nan(prec: u32) -> Self {
125 match prec.next_power_of_two() {
126 512 => Self::D512(fastnum::D512::NAN),
127 256 => Self::D256(fastnum::D256::NAN),
128 _ => unreachable!(),
129 }
130 }
131 fn inf(prec: u32) -> Self {
132 match prec.next_power_of_two() {
133 512 => Self::D512(fastnum::D512::INFINITY),
134 256 => Self::D256(fastnum::D256::INFINITY),
135 _ => unreachable!(),
136 }
137 }
138}
139
140impl Display for Decimal {
141 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
142 match self {
143 Self::D512(a) => a.fmt(f),
144 Self::D256(a) => a.fmt(f),
145 }
146 }
147}
148impl PartialEq<f64> for Decimal {
149 fn eq(&self, other: &f64) -> bool {
150 match self {
151 Decimal::D512(a) => &a.to_f64() == other,
152 Decimal::D256(b) => &b.to_f64() == other,
153 }
154 }
155}
156impl PartialEq<i32> for Decimal {
157 fn eq(&self, other: &i32) -> bool {
158 match self {
159 Decimal::D512(a) => a.to_f64() == *other as f64,
160 Decimal::D256(b) => b.to_f64() == *other as f64,
161 }
162 }
163}
164impl_rem!(Decimal, (D512, |x| x), (D256, |x| x));
165impl_new_val_deci!(Decimal);
166impl_partial_ord!(
167 Decimal,
168 (D512, |x: &fastnum::D512| x.to_f64()),
169 (D256, |x: &fastnum::D256| x.to_f64())
170);
171dec_impl!(Decimal, D512, D256);
172impl_neg!(Decimal, D512, D256);
173impl_self_ops!(
174 Decimal,
175 (D512, |x: &fastnum::D512| *x),
176 (D256, |x: &fastnum::D256| *x)
177);