1use crate::DecimalSeparatorStyle;
2use crate::error::{FendError, Interrupt};
3use crate::format::Format;
4use crate::num::Exact;
5use crate::num::bigrat::{BigRat, FormattedBigRat};
6use crate::num::{Base, FormattingStyle};
7use crate::result::FResult;
8use crate::serialize::{Deserialize, Serialize};
9use std::cmp::Ordering;
10use std::ops::Neg;
11use std::{fmt, hash, io};
12
13use super::bigrat;
14use super::biguint::BigUint;
15
16#[derive(Clone)]
17pub(crate) struct Real {
18 pattern: Pattern,
19}
20
21impl fmt::Debug for Real {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match &self.pattern {
24 Pattern::Simple(x) => write!(f, "{x:?}"),
25 Pattern::Pi(x) => {
26 if x.is_definitely_one() {
27 write!(f, "pi")
28 } else {
29 write!(f, "{x:?} * pi")
30 }
31 }
32 }
33 }
34}
35
36#[derive(Clone, Debug)]
37pub(crate) enum Pattern {
38 Simple(BigRat),
40 Pi(BigRat),
42}
43
44impl hash::Hash for Real {
45 fn hash<H: hash::Hasher>(&self, state: &mut H) {
46 match &self.pattern {
47 Pattern::Simple(r) | Pattern::Pi(r) => r.hash(state),
48 }
49 }
50}
51
52impl Real {
53 pub(crate) fn compare<I: Interrupt>(&self, other: &Self, int: &I) -> FResult<Ordering> {
54 Ok(match (&self.pattern, &other.pattern) {
55 (Pattern::Simple(a), Pattern::Simple(b)) | (Pattern::Pi(a), Pattern::Pi(b)) => a.cmp(b),
56 _ => {
57 let a = self.clone().approximate(int)?;
58 let b = other.clone().approximate(int)?;
59 a.cmp(&b)
60 }
61 })
62 }
63
64 pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FResult<()> {
65 match &self.pattern {
66 Pattern::Simple(s) => {
67 1u8.serialize(write)?;
68 s.serialize(write)?;
69 }
70 Pattern::Pi(n) => {
71 2u8.serialize(write)?;
72 n.serialize(write)?;
73 }
74 }
75 Ok(())
76 }
77
78 pub(crate) fn deserialize(read: &mut impl io::Read) -> FResult<Self> {
79 Ok(Self {
80 pattern: match u8::deserialize(read)? {
81 1 => Pattern::Simple(BigRat::deserialize(read)?),
82 2 => Pattern::Pi(BigRat::deserialize(read)?),
83 _ => return Err(FendError::DeserializationError),
84 },
85 })
86 }
87
88 pub(crate) fn is_integer(&self) -> bool {
89 match &self.pattern {
90 Pattern::Simple(s) => s.is_integer(),
91 Pattern::Pi(_) => false,
92 }
93 }
94
95 fn approximate<I: Interrupt>(self, int: &I) -> FResult<BigRat> {
96 match self.pattern {
97 Pattern::Simple(s) => Ok(s),
98 Pattern::Pi(n) => {
99 let required_accuracy_dp = 20;
100 let mut pi = BigRat::from(0);
101 for k in 0..=(required_accuracy_dp / 14) {
102 let mut term = BigRat::from(1);
103 if k % 2 == 1 {
104 term = -term;
105 }
106 let k = BigRat::from(k);
107 term = term.mul(&BigRat::from(6).mul(&k, int)?.factorial(int)?, int)?;
108 term = term.mul(
109 &BigRat::from(545_140_134)
110 .mul(&k, int)?
111 .add(BigRat::from(13_591_409), int)?,
112 int,
113 )?;
114 term = term.div(&BigRat::from(3).mul(&k, int)?.factorial(int)?, int)?;
115 term = term.div(
116 &k.clone().factorial(int)?.pow(BigRat::from(3), int)?.value,
117 int,
118 )?;
119 term = term.div(
120 &BigRat::from(640_320)
121 .pow(
122 BigRat::from(3)
123 .mul(&k, int)?
124 .add(BigRat::from(3).div(&BigRat::from(2), int)?, int)?,
125 int,
126 )?
127 .value,
128 int,
129 )?;
130 pi = pi.add(term, int)?;
131 }
132 pi = pi.mul(&BigRat::from(12), int)?;
133 pi = pi.pow(-BigRat::from(1), int)?.value;
134 Ok(n.mul(&pi, int)?)
135 }
136 }
137 }
138
139 pub(crate) fn try_as_biguint<I: Interrupt>(self, int: &I) -> FResult<BigUint> {
140 match self.pattern {
141 Pattern::Simple(s) => s.try_as_biguint(int),
142 Pattern::Pi(n) => {
143 if n == 0.into() {
144 Ok(BigUint::Small(0))
145 } else {
146 Err(FendError::CannotConvertToInteger)
147 }
148 }
149 }
150 }
151
152 pub(crate) fn try_as_i64<I: Interrupt>(self, int: &I) -> FResult<i64> {
153 match self.pattern {
154 Pattern::Simple(s) => s.try_as_i64(int),
155 Pattern::Pi(n) => {
156 if n == 0.into() {
157 Ok(0)
158 } else {
159 Err(FendError::CannotConvertToInteger)
160 }
161 }
162 }
163 }
164
165 pub(crate) fn try_as_usize<I: Interrupt>(self, int: &I) -> FResult<usize> {
166 match self.pattern {
167 Pattern::Simple(s) => s.try_as_usize(int),
168 Pattern::Pi(n) => {
169 if n == 0.into() {
170 Ok(0)
171 } else {
172 Err(FendError::CannotConvertToInteger)
173 }
174 }
175 }
176 }
177
178 pub(crate) fn sin<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
180 Ok(match self.pattern {
181 Pattern::Simple(s) => s.sin(int)?.apply(Self::from),
182 Pattern::Pi(n) => {
183 if n < 0.into() {
184 let s = Self {
185 pattern: Pattern::Pi(n),
186 };
187 return Ok(-Self::sin(-s, int)?);
189 }
190 if let Ok(integer) = n.clone().mul(&6.into(), int)?.try_as_usize(int) {
191 if integer.is_multiple_of(6) {
193 return Ok(Exact::new(Self::from(0), true));
194 } else if integer % 12 == 3 {
195 return Ok(Exact::new(Self::from(1), true));
196 } else if integer % 12 == 9 {
197 return Ok(Exact::new(-Self::from(1), true));
198 } else if integer % 12 == 1 || integer % 12 == 5 {
199 return Exact::new(Self::from(1), true)
200 .div(&Exact::new(2.into(), true), int);
201 } else if integer % 12 == 7 || integer % 12 == 11 {
202 return Exact::new(-Self::from(1), true)
203 .div(&Exact::new(2.into(), true), int);
204 }
205 }
206 let s = Self {
207 pattern: Pattern::Pi(n),
208 };
209 s.approximate(int)?.sin(int)?.apply(Self::from)
210 }
211 })
212 }
213
214 pub(crate) fn cos<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
215 let half_pi = Exact::new(Self::pi(), true).div(&Exact::new(Self::from(2), true), int)?;
217 Exact::new(self, true).add(half_pi, int)?.value.sin(int)
218 }
219
220 pub(crate) fn asin<I: Interrupt>(self, int: &I) -> FResult<Self> {
221 Ok(Self::from(self.approximate(int)?.asin(int)?))
222 }
223
224 pub(crate) fn acos<I: Interrupt>(self, int: &I) -> FResult<Self> {
225 Ok(Self::from(self.approximate(int)?.acos(int)?))
226 }
227
228 pub(crate) fn atan<I: Interrupt>(self, int: &I) -> FResult<Self> {
229 Ok(Self::from(self.approximate(int)?.atan(int)?))
230 }
231
232 pub(crate) fn atan2<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
233 Ok(Self::from(
234 self.approximate(int)?.atan2(rhs.approximate(int)?, int)?,
235 ))
236 }
237
238 pub(crate) fn sinh<I: Interrupt>(self, int: &I) -> FResult<Self> {
239 Ok(Self::from(self.approximate(int)?.sinh(int)?))
240 }
241
242 pub(crate) fn cosh<I: Interrupt>(self, int: &I) -> FResult<Self> {
243 Ok(Self::from(self.approximate(int)?.cosh(int)?))
244 }
245
246 pub(crate) fn tanh<I: Interrupt>(self, int: &I) -> FResult<Self> {
247 Ok(Self::from(self.approximate(int)?.tanh(int)?))
248 }
249
250 pub(crate) fn asinh<I: Interrupt>(self, int: &I) -> FResult<Self> {
251 Ok(Self::from(self.approximate(int)?.asinh(int)?))
252 }
253
254 pub(crate) fn acosh<I: Interrupt>(self, int: &I) -> FResult<Self> {
255 Ok(Self::from(self.approximate(int)?.acosh(int)?))
256 }
257
258 pub(crate) fn atanh<I: Interrupt>(self, int: &I) -> FResult<Self> {
259 Ok(Self::from(self.approximate(int)?.atanh(int)?))
260 }
261
262 pub(crate) fn ln<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
264 Ok(self.approximate(int)?.ln(int)?.apply(Self::from))
265 }
266
267 pub(crate) fn log2<I: Interrupt>(self, int: &I) -> FResult<Self> {
268 Ok(Self::from(self.approximate(int)?.log2(int)?))
269 }
270
271 pub(crate) fn log10<I: Interrupt>(self, int: &I) -> FResult<Self> {
272 Ok(Self::from(self.approximate(int)?.log10(int)?))
273 }
274
275 pub(crate) fn factorial<I: Interrupt>(self, int: &I) -> FResult<Self> {
276 Ok(Self::from(self.approximate(int)?.factorial(int)?))
277 }
278
279 pub(crate) fn floor<I: Interrupt>(self, int: &I) -> FResult<Self> {
280 Ok(Self::from(self.approximate(int)?.floor(int)?))
281 }
282
283 pub(crate) fn ceil<I: Interrupt>(self, int: &I) -> FResult<Self> {
284 Ok(Self::from(self.approximate(int)?.ceil(int)?))
285 }
286
287 pub(crate) fn round<I: Interrupt>(self, int: &I) -> FResult<Self> {
288 Ok(Self::from(self.approximate(int)?.round(int)?))
289 }
290
291 pub(crate) fn format<I: Interrupt>(
292 &self,
293 base: Base,
294 mut style: FormattingStyle,
295 imag: bool,
296 use_parens_if_fraction: bool,
297 decimal_separator: DecimalSeparatorStyle,
298 int: &I,
299 ) -> FResult<Exact<Formatted>> {
300 let mut pi = false;
301 if style == FormattingStyle::Exact
302 && !self.is_zero()
303 && let Pattern::Pi(_) = self.pattern
304 {
305 pi = true;
306 }
307
308 let term = match (imag, pi) {
309 (false, false) => "",
310 (false, true) => "\u{3c0}", (true, false) => "i",
312 (true, true) => "\u{3c0}i",
313 };
314
315 let mut override_exact = true;
316
317 let rat = match &self.pattern {
318 Pattern::Simple(f) => f,
319 Pattern::Pi(f) => {
320 if pi {
321 f
322 } else {
323 override_exact = false;
324 if style == FormattingStyle::Auto {
325 style = FormattingStyle::DecimalPlaces(10);
326 }
327 &self.clone().approximate(int)?
328 }
329 }
330 };
331
332 let formatted = rat.format(
333 &bigrat::FormatOptions {
334 base,
335 style,
336 term,
337 use_parens_if_fraction,
338 decimal_separator,
339 },
340 int,
341 )?;
342 let exact = formatted.exact && override_exact;
343 Ok(Exact::new(
344 Formatted {
345 num: formatted.value,
346 },
347 exact,
348 ))
349 }
350
351 pub(crate) fn exp<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
352 Ok(self.approximate(int)?.exp(int)?.apply(Self::from))
353 }
354
355 pub(crate) fn pow<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Exact<Self>> {
356 if let Pattern::Simple(n) = &rhs.pattern
358 && n == &1.into()
359 {
360 return Ok(Exact::new(self, true));
361 }
362
363 if let Pattern::Simple(n) = &self.pattern
365 && n == &1.into()
366 {
367 return Ok(Exact::new(1.into(), true));
368 }
369
370 if let (Pattern::Simple(a), Pattern::Simple(b)) =
371 (self.clone().pattern, rhs.clone().pattern)
372 {
373 Ok(a.pow(b, int)?.apply(Self::from))
374 } else {
375 Ok(self
376 .approximate(int)?
377 .pow(rhs.approximate(int)?, int)?
378 .combine(false)
379 .apply(Self::from))
380 }
381 }
382
383 pub(crate) fn root_n<I: Interrupt>(self, n: &Self, int: &I) -> FResult<Exact<Self>> {
384 Ok(match self.pattern {
388 Pattern::Simple(a) => match &n.pattern {
389 Pattern::Simple(b) => a.root_n(b, int)?.apply(Self::from),
390 Pattern::Pi(_) => {
391 let b = n.clone().approximate(int)?;
392 a.root_n(&b, int)?.apply(Self::from).combine(false)
393 }
394 },
395 Pattern::Pi(_) => {
396 let a = self.clone().approximate(int)?;
397 let b = n.clone().approximate(int)?;
398 a.root_n(&b, int)?.apply(Self::from).combine(false)
399 }
400 })
401 }
402
403 pub(crate) fn pi() -> Self {
404 Self {
405 pattern: Pattern::Pi(1.into()),
406 }
407 }
408
409 pub(crate) fn is_zero(&self) -> bool {
410 match &self.pattern {
411 Pattern::Simple(a) | Pattern::Pi(a) => a.is_definitely_zero() || a == &0.into(),
412 }
413 }
414
415 pub(crate) fn is_pos(&self) -> bool {
416 match &self.pattern {
417 Pattern::Simple(a) | Pattern::Pi(a) => !a.is_definitely_zero() && a > &0.into(),
418 }
419 }
420
421 pub(crate) fn is_neg(&self) -> bool {
422 match &self.pattern {
423 Pattern::Simple(a) | Pattern::Pi(a) => !a.is_definitely_zero() && a < &0.into(),
424 }
425 }
426
427 pub(crate) fn between_plus_minus_one_incl<I: Interrupt>(&self, int: &I) -> FResult<bool> {
428 Ok(Self::from(1).neg().compare(self, int)? != Ordering::Greater
430 && self.compare(&1.into(), int)? != Ordering::Greater)
431 }
432
433 pub(crate) fn between_plus_minus_one_excl<I: Interrupt>(&self, int: &I) -> FResult<bool> {
434 Ok(Self::from(1).neg().compare(self, int)? == Ordering::Less
436 && self.compare(&1.into(), int)? == Ordering::Less)
437 }
438
439 pub(crate) fn is_definitely_zero(&self) -> bool {
440 match &self.pattern {
441 Pattern::Simple(a) | Pattern::Pi(a) => a.is_definitely_zero(),
442 }
443 }
444
445 pub(crate) fn is_definitely_one(&self) -> bool {
446 match &self.pattern {
447 Pattern::Simple(a) => a.is_definitely_one(),
448 Pattern::Pi(_) => false,
449 }
450 }
451
452 pub(crate) fn expect_rational(self) -> FResult<BigRat> {
453 match self.pattern {
454 Pattern::Simple(a) => Ok(a),
455 Pattern::Pi(_) => Err(FendError::ExpectedARationalNumber),
456 }
457 }
458
459 pub(crate) fn modulo<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
460 Ok(Self::from(
461 self.expect_rational()?
462 .modulo(rhs.expect_rational()?, int)?,
463 ))
464 }
465
466 pub(crate) fn bitwise<I: Interrupt>(
467 self,
468 rhs: Self,
469 op: crate::ast::BitwiseBop,
470 int: &I,
471 ) -> FResult<Self> {
472 Ok(Self::from(self.expect_rational()?.bitwise(
473 rhs.expect_rational()?,
474 op,
475 int,
476 )?))
477 }
478
479 pub(crate) fn combination<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
480 Ok(Self::from(
481 self.expect_rational()?
482 .combination(rhs.expect_rational()?, int)?,
483 ))
484 }
485
486 pub(crate) fn permutation<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
487 Ok(Self::from(
488 self.expect_rational()?
489 .permutation(rhs.expect_rational()?, int)?,
490 ))
491 }
492}
493
494impl Exact<Real> {
495 pub(crate) fn add<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
496 if self.exact && self.value.is_zero() {
497 return Ok(rhs);
498 } else if rhs.exact && rhs.value.is_zero() {
499 return Ok(self);
500 }
501 let args_exact = self.exact && rhs.exact;
502 Ok(
503 match (self.clone().value.pattern, rhs.clone().value.pattern) {
504 (Pattern::Simple(a), Pattern::Simple(b)) => {
505 Self::new(a.add(b, int)?.into(), args_exact)
506 }
507 (Pattern::Pi(a), Pattern::Pi(b)) => Self::new(
508 Real {
509 pattern: Pattern::Pi(a.add(b, int)?),
510 },
511 args_exact,
512 ),
513 _ => {
514 let a = self.value.approximate(int)?;
515 let b = rhs.value.approximate(int)?;
516 Self::new(a.add(b, int)?.into(), false)
517 }
518 },
519 )
520 }
521
522 pub(crate) fn mul<I: Interrupt>(self, rhs: Exact<&Real>, int: &I) -> FResult<Self> {
523 if self.exact && self.value.is_zero() {
524 return Ok(self);
525 } else if rhs.exact && rhs.value.is_zero() {
526 return Ok(Self::new(rhs.value.clone(), rhs.exact));
527 }
528 let args_exact = self.exact && rhs.exact;
529 Ok(match self.value.pattern {
530 Pattern::Simple(a) => match &rhs.value.pattern {
531 Pattern::Simple(b) => Self::new(a.mul(b, int)?.into(), args_exact),
532 Pattern::Pi(b) => Self::new(
533 Real {
534 pattern: Pattern::Pi(a.mul(b, int)?),
535 },
536 args_exact,
537 ),
538 },
539 Pattern::Pi(a) => match &rhs.value.pattern {
540 Pattern::Simple(b) => Self::new(
541 Real {
542 pattern: Pattern::Pi(a.mul(b, int)?),
543 },
544 args_exact,
545 ),
546 Pattern::Pi(_) => Self::new(
547 Real {
548 pattern: Pattern::Pi(a.mul(&rhs.value.clone().approximate(int)?, int)?),
549 },
550 false,
551 ),
552 },
553 })
554 }
555
556 pub(crate) fn div<I: Interrupt>(self, rhs: &Self, int: &I) -> FResult<Self> {
557 if rhs.value.is_zero() {
558 return Err(FendError::DivideByZero);
559 }
560 if self.exact && self.value.is_zero() {
561 return Ok(self);
562 }
563 Ok(match self.value.pattern {
564 Pattern::Simple(a) => match &rhs.value.pattern {
565 Pattern::Simple(b) => Self::new(a.div(b, int)?.into(), self.exact && rhs.exact),
566 Pattern::Pi(_) => Self::new(
567 a.div(&rhs.value.clone().approximate(int)?, int)?.into(),
568 false,
569 ),
570 },
571 Pattern::Pi(a) => match &rhs.value.pattern {
572 Pattern::Simple(b) => Self::new(
573 Real {
574 pattern: Pattern::Pi(a.div(b, int)?),
575 },
576 self.exact && rhs.exact,
577 ),
578 Pattern::Pi(b) => Self::new(a.div(b, int)?.into(), self.exact && rhs.exact),
579 },
580 })
581 }
582}
583
584impl Neg for Real {
585 type Output = Self;
586
587 fn neg(self) -> Self {
588 match self.pattern {
589 Pattern::Simple(s) => Self::from(-s),
590 Pattern::Pi(n) => Self {
591 pattern: Pattern::Pi(-n),
592 },
593 }
594 }
595}
596
597impl From<u64> for Real {
598 fn from(i: u64) -> Self {
599 Self {
600 pattern: Pattern::Simple(i.into()),
601 }
602 }
603}
604
605impl From<BigRat> for Real {
606 fn from(n: BigRat) -> Self {
607 Self {
608 pattern: Pattern::Simple(n),
609 }
610 }
611}
612
613#[derive(Debug)]
614pub(crate) struct Formatted {
615 num: FormattedBigRat,
616}
617
618impl fmt::Display for Formatted {
619 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
620 write!(f, "{}", self.num)
621 }
622}