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