1use crate::{
26 exceptions::Exception,
27 gc::Trace,
28 ports::{BufferMode, Port, Transcoder},
29 registry::bridge,
30 strings::WideString,
31 syntax::{Span, lex::Lexer},
32 value::{Value, ValueType},
33};
34use core::f64;
35use malachite::{
36 Integer,
37 base::{
38 num::{
39 arithmetic::traits::{FloorSqrt, Parity, Pow},
40 conversion::traits::{ConvertibleFrom, RoundingFrom, WrappingFrom},
41 },
42 rounding_modes::RoundingMode,
43 },
44 rational::Rational,
45};
46use num::ToPrimitive;
47use scheme_rs_macros::{maybe_async, maybe_await};
48use std::{
49 cmp::Ordering,
50 fmt,
51 hash::Hash,
52 io::Cursor,
53 ops::{Add, Div, Mul, Neg, Rem, Sub},
54 sync::Arc,
55};
56
57#[repr(align(16))]
58pub(crate) enum NumberInner {
59 Simple(SimpleNumber),
60 Complex(ComplexNumber),
61}
62
63#[derive(Clone, Trace)]
65pub struct Number(pub(crate) Arc<NumberInner>);
66
67macro_rules! number_dispatch_method {
68 ( $func:ident ) => {
69 pub fn $func(&self) -> Self {
70 match self.0.as_ref() {
71 NumberInner::Simple(simple) => Number::from(simple.$func()),
72 NumberInner::Complex(complex) => Number::from(complex.$func()),
73 }
74 }
75 };
76}
77
78impl Number {
79 pub fn as_simple(&self) -> Option<&SimpleNumber> {
80 match self.0.as_ref() {
81 NumberInner::Simple(simple) => Some(simple),
82 NumberInner::Complex(_) => None,
83 }
84 }
85
86 pub fn as_complex(&self) -> Option<&ComplexNumber> {
87 match self.0.as_ref() {
88 NumberInner::Complex(complex) => Some(complex),
89 NumberInner::Simple(_) => None,
90 }
91 }
92
93 pub fn is_zero(&self) -> bool {
94 match self.0.as_ref() {
95 NumberInner::Simple(simple) => simple.is_zero(),
96 NumberInner::Complex(complex) => complex.re.is_zero() && complex.im.is_zero(),
97 }
98 }
99
100 pub fn is_integer(&self) -> bool {
101 match self.0.as_ref() {
102 NumberInner::Simple(simple) => simple.is_integer(),
103 NumberInner::Complex(complex) => {
104 complex.im.is_exact() && complex.im.is_zero() && complex.re.is_integer()
105 }
106 }
107 }
108
109 pub fn is_rational(&self) -> bool {
110 match self.0.as_ref() {
111 NumberInner::Simple(simple) => simple.is_rational(),
112 NumberInner::Complex(complex) => {
113 complex.im.is_exact() && complex.im.is_zero() && complex.re.is_rational()
114 }
115 }
116 }
117
118 pub fn is_real(&self) -> bool {
119 match self.0.as_ref() {
120 NumberInner::Simple(_) => true,
121 NumberInner::Complex(complex) => complex.im.is_exact() && complex.im.is_zero(),
122 }
123 }
124
125 pub fn is_integer_valued(&self) -> bool {
126 match self.0.as_ref() {
127 NumberInner::Simple(simple) => simple.is_integer(),
128 NumberInner::Complex(complex) => complex.im.is_zero() && complex.re.is_integer(),
129 }
130 }
131
132 pub fn is_rational_valued(&self) -> bool {
133 match self.0.as_ref() {
134 NumberInner::Simple(simple) => simple.is_rational(),
135 NumberInner::Complex(complex) => complex.im.is_zero() && complex.re.is_rational(),
136 }
137 }
138
139 pub fn is_real_valued(&self) -> bool {
140 match self.0.as_ref() {
141 NumberInner::Simple(_) => true,
142 NumberInner::Complex(complex) => complex.im.is_zero(),
143 }
144 }
145
146 pub fn is_complex(&self) -> bool {
148 true
149 }
150
151 pub fn is_exact(&self) -> bool {
152 match self.0.as_ref() {
153 NumberInner::Simple(simple) => simple.is_exact(),
154 NumberInner::Complex(complex) => complex.im.is_exact() && complex.re.is_exact(),
155 }
156 }
157
158 pub fn is_inexact(&self) -> bool {
159 match self.0.as_ref() {
160 NumberInner::Simple(simple) => !simple.is_exact(),
161 NumberInner::Complex(complex) => !complex.im.is_exact() || !complex.re.is_exact(),
162 }
163 }
164
165 pub fn inexact(self) -> Number {
166 match self.0.as_ref() {
167 NumberInner::Simple(simple) => Number::from(simple.inexact()),
168 NumberInner::Complex(complex) => Number::from(complex.inexact()),
169 }
170 }
171
172 pub fn exact(self) -> Number {
173 match self.0.as_ref() {
174 NumberInner::Simple(simple) => Number::from(simple.exact()),
175 NumberInner::Complex(complex) => Number::from(complex.exact()),
176 }
177 }
178
179 pub fn eqv(&self, rhs: &Self) -> bool {
180 match (self.0.as_ref(), rhs.0.as_ref()) {
181 (NumberInner::Simple(lhs), NumberInner::Simple(rhs)) => lhs.eqv(rhs),
182 (NumberInner::Complex(lhs), NumberInner::Simple(rhs))
183 if lhs.im.is_zero() && lhs.im.is_exact() == rhs.is_exact() =>
184 {
185 lhs.re.eqv(rhs)
186 }
187 (NumberInner::Simple(lhs), NumberInner::Complex(rhs))
188 if rhs.im.is_zero() && rhs.im.is_exact() == lhs.is_exact() =>
189 {
190 lhs.eqv(&rhs.re)
191 }
192 (NumberInner::Complex(lhs), NumberInner::Complex(rhs)) => {
193 lhs.re.eqv(&rhs.re) && lhs.im.eqv(&rhs.im)
194 }
195 _ => false,
196 }
197 }
198
199 pub fn pow(&self, rhs: &Number) -> Number {
200 match (self.0.as_ref(), rhs.0.as_ref()) {
201 (NumberInner::Simple(base), NumberInner::Simple(exp)) => Number::from(base.pow(exp)),
202 (NumberInner::Simple(base), NumberInner::Complex(exp)) => {
203 Number::from(ComplexNumber::new(base.clone(), SimpleNumber::zero()).powc(exp))
204 }
205 (NumberInner::Complex(base), NumberInner::Simple(exp)) => {
206 Number::from(base.powc(&ComplexNumber::new(exp.clone(), SimpleNumber::zero())))
207 }
208 (NumberInner::Complex(base), NumberInner::Complex(exp)) => Number::from(base.powc(exp)),
209 }
210 }
211
212 number_dispatch_method!(exp);
213 number_dispatch_method!(ln);
214 number_dispatch_method!(sqrt);
215 number_dispatch_method!(sin);
216 number_dispatch_method!(cos);
217 number_dispatch_method!(tan);
218 number_dispatch_method!(asin);
222 number_dispatch_method!(acos);
223 number_dispatch_method!(atan);
224}
225
226impl From<NumberInner> for Number {
227 fn from(value: NumberInner) -> Self {
228 Self(Arc::new(value))
229 }
230}
231
232impl<T> From<T> for Number
233where
234 SimpleNumber: From<T>,
235{
236 fn from(value: T) -> Self {
237 Self(Arc::new(NumberInner::Simple(SimpleNumber::from(value))))
238 }
239}
240
241macro_rules! impl_simple_number_int_conversion_for_num {
242 ($ty:ty) => {
243 impl TryFrom<&Number> for $ty {
244 type Error = Exception;
245
246 fn try_from(num: &Number) -> Result<$ty, Self::Error> {
247 match num.0.as_ref() {
248 NumberInner::Simple(simple) => simple.try_into(),
249 NumberInner::Complex(complex)
250 if complex.im.is_exact() && complex.im.is_zero() =>
251 {
252 <$ty as TryFrom<&SimpleNumber>>::try_from(&complex.re)
253 }
254 _ => Err(Exception::conversion_error(stringify!($ty), "complex")),
255 }
256 }
257 }
258
259 impl TryFrom<Number> for $ty {
260 type Error = Exception;
261
262 fn try_from(num: Number) -> Result<$ty, Self::Error> {
263 <$ty as TryFrom<&Number>>::try_from(&num)
264 }
265 }
266
267 impl From<&Number> for Option<$ty> {
268 fn from(num: &Number) -> Option<$ty> {
269 match num.0.as_ref() {
270 NumberInner::Simple(simple) => simple.into(),
271 NumberInner::Complex(complex)
272 if complex.im.is_exact() && complex.im.is_zero() =>
273 {
274 <Option<$ty> as From<&SimpleNumber>>::from(&complex.re)
275 }
276 _ => None,
277 }
278 }
279 }
280
281 impl From<Number> for Option<$ty> {
282 fn from(num: Number) -> Option<$ty> {
283 Self::from(&num)
284 }
285 }
286 };
287}
288
289impl_simple_number_int_conversion_for_num!(u8);
290impl_simple_number_int_conversion_for_num!(u16);
291impl_simple_number_int_conversion_for_num!(u32);
292impl_simple_number_int_conversion_for_num!(u64);
293impl_simple_number_int_conversion_for_num!(u128);
294impl_simple_number_int_conversion_for_num!(usize);
295impl_simple_number_int_conversion_for_num!(i8);
296impl_simple_number_int_conversion_for_num!(i16);
297impl_simple_number_int_conversion_for_num!(i32);
298impl_simple_number_int_conversion_for_num!(i64);
299impl_simple_number_int_conversion_for_num!(i128);
300impl_simple_number_int_conversion_for_num!(isize);
301impl_simple_number_int_conversion_for_num!(Integer);
302
303#[derive(Clone)]
305#[repr(align(16))]
306pub enum SimpleNumber {
307 FixedInteger(i64),
308 BigInteger(Integer),
309 Rational(Rational),
310 Real(f64),
311}
312
313impl SimpleNumber {
314 pub fn zero() -> Self {
315 Self::FixedInteger(0)
316 }
317
318 pub fn one() -> Self {
319 Self::FixedInteger(1)
320 }
321
322 pub fn infinity() -> Self {
323 Self::Real(f64::INFINITY)
324 }
325
326 pub fn neg_infinity() -> Self {
327 Self::Real(f64::NEG_INFINITY)
328 }
329
330 pub fn is_zero(&self) -> bool {
331 match self {
332 SimpleNumber::FixedInteger(i) => *i == 0,
333 SimpleNumber::BigInteger(i) => *i == 0,
334 SimpleNumber::Rational(r) => *r == 0,
335 SimpleNumber::Real(r) => *r == 0.0,
336 }
337 }
338
339 pub fn is_one(&self) -> bool {
340 match self {
341 SimpleNumber::FixedInteger(i) => *i == 1,
342 SimpleNumber::BigInteger(i) => *i == 1,
343 SimpleNumber::Rational(r) => *r == 1,
344 SimpleNumber::Real(r) => *r == 1.0,
345 }
346 }
347
348 pub fn is_neg_one(&self) -> bool {
349 match self {
350 SimpleNumber::FixedInteger(i) => *i == -1,
351 SimpleNumber::BigInteger(i) => *i == -1,
352 SimpleNumber::Rational(r) => *r == -1,
353 SimpleNumber::Real(r) => *r == -1.0,
354 }
355 }
356
357 pub fn is_exact(&self) -> bool {
358 matches!(
359 self,
360 Self::FixedInteger(_) | Self::BigInteger(_) | Self::Rational(_)
361 )
362 }
363
364 pub fn to_string(&self, radix: u32, precision: Option<usize>) -> Option<String> {
365 match radix {
366 2 => match self {
367 SimpleNumber::FixedInteger(i) => Some(format!("{i:b}")),
368 SimpleNumber::BigInteger(i) => Some(format!("{i:b}")),
369 SimpleNumber::Rational(r) => {
370 let (n, d) = r.numerator_and_denominator_ref();
371 if *r < 0 {
372 Some(format!("-{n:b}/{d:b}"))
373 } else {
374 Some(format!("{n:b}/{d:b}"))
375 }
376 }
377 SimpleNumber::Real(_) => None,
378 },
379 8 => match self {
380 SimpleNumber::FixedInteger(i) => Some(format!("{i:o}")),
381 SimpleNumber::BigInteger(i) => Some(format!("{i:o}")),
382 SimpleNumber::Rational(r) => {
383 let (n, d) = r.numerator_and_denominator_ref();
384 if *r < 0 {
385 Some(format!("-{n:o}/{d:o}"))
386 } else {
387 Some(format!("{n:o}/{d:o}"))
388 }
389 }
390 SimpleNumber::Real(_) => None,
391 },
392 10 => match self {
393 SimpleNumber::FixedInteger(i) => Some(format!("{i}")),
394 SimpleNumber::BigInteger(i) => Some(format!("{i}")),
395 SimpleNumber::Rational(r) => Some(format!("{r}")),
396 SimpleNumber::Real(r) => {
397 if let Some(precision) = precision {
398 Some(format!("{r:.precision$}"))
399 } else {
400 Some(format!("{r}"))
401 }
402 }
403 },
404 16 => match self {
405 SimpleNumber::FixedInteger(i) => Some(format!("{i:X}")),
406 SimpleNumber::BigInteger(i) => Some(format!("{i:X}")),
407 SimpleNumber::Rational(r) => {
408 let (n, d) = r.numerator_and_denominator_ref();
409 if *r < 0 {
410 Some(format!("-{n:X}/{d:X}"))
411 } else {
412 Some(format!("{n:X}/{d:X}"))
413 }
414 }
415 SimpleNumber::Real(_) => None,
416 },
417 _ => None,
418 }
419 }
420
421 pub fn is_nan(&self) -> bool {
422 if let Self::Real(real) = self {
423 real.is_nan()
424 } else {
425 false
426 }
427 }
428
429 pub fn is_finite(&self) -> bool {
430 matches!(self, Self::Real(r) if r.is_finite())
431 }
432
433 pub fn is_infinite(&self) -> bool {
434 if let Self::Real(real) = self {
435 real.is_infinite()
436 } else {
437 false
438 }
439 }
440
441 pub fn is_negative(&self) -> bool {
442 match self {
443 SimpleNumber::FixedInteger(i) => i.is_negative(),
444 SimpleNumber::BigInteger(i) => *i < 0i32,
445 SimpleNumber::Rational(r) => *r < 0i32,
446 SimpleNumber::Real(r) => r.is_sign_negative(),
447 }
448 }
449
450 pub fn is_positive(&self) -> bool {
451 match self {
452 SimpleNumber::FixedInteger(i) => i.is_positive(),
453 SimpleNumber::BigInteger(i) => *i >= 0i32,
454 SimpleNumber::Rational(r) => *r >= 0i32,
455 SimpleNumber::Real(r) => r.is_sign_positive(),
456 }
457 }
458
459 pub fn is_integer(&self) -> bool {
460 match self {
461 SimpleNumber::FixedInteger(_) | SimpleNumber::BigInteger(_) => true,
462 SimpleNumber::Rational(r) => *r.denominator_ref() == 1u32,
463 SimpleNumber::Real(r) => r.fract() == 0.0,
464 }
465 }
466
467 pub fn is_rational(&self) -> bool {
468 match self {
469 SimpleNumber::FixedInteger(_)
470 | SimpleNumber::BigInteger(_)
471 | SimpleNumber::Rational(_) => true,
472 SimpleNumber::Real(r) => !r.is_infinite() && !r.is_nan(),
473 }
474 }
475
476 pub fn to_integer(&self, rounding_mode: RoundingMode) -> Self {
477 match self {
478 Self::FixedInteger(i) => Self::FixedInteger(*i),
479 Self::BigInteger(i) => Self::BigInteger(i.clone()),
480 Self::Rational(r) => Self::BigInteger(Integer::rounding_from(r, rounding_mode).0),
481 Self::Real(r) if r.is_nan() || r.is_infinite() => Self::Real(*r),
482 Self::Real(r) => Self::BigInteger(Integer::rounding_from(*r, rounding_mode).0),
483 }
484 }
485
486 pub fn inexact(&self) -> Self {
487 match self {
488 Self::FixedInteger(i) => Self::Real(*i as f64),
489 Self::BigInteger(i) => Self::Real(f64::rounding_from(i, RoundingMode::Nearest).0),
490 Self::Rational(r) => Self::Real(f64::rounding_from(r, RoundingMode::Nearest).0),
491 Self::Real(r) => Self::Real(*r),
492 }
493 }
494
495 pub fn exact(&self) -> Self {
496 match self {
497 Self::Real(r) if !r.is_nan() && !r.is_infinite() && r.fract() == 0.0 => {
499 Self::BigInteger(Integer::rounding_from(*r, RoundingMode::Nearest).0)
500 }
501 Self::Real(r) => match Rational::try_from_float_simplest(*r) {
502 Ok(r) => Self::Rational(r),
503 _ => self.clone(),
504 },
505 num => num.clone(),
506 }
507 }
508
509 pub fn abs(&self) -> Self {
510 if *self < SimpleNumber::zero() {
511 -self
512 } else {
513 self.clone()
514 }
515 }
516
517 pub fn powi(&self, p: i32) -> Self {
518 match self {
519 SimpleNumber::FixedInteger(i) => i.checked_pow(p as u32).map_or_else(
520 || SimpleNumber::BigInteger(Integer::from(*i).pow(p as u64)),
521 SimpleNumber::FixedInteger,
522 ),
523 SimpleNumber::BigInteger(i) => SimpleNumber::BigInteger(i.pow(p as u64)),
524 SimpleNumber::Rational(r) => SimpleNumber::Rational(r.pow(p as u64)),
525 SimpleNumber::Real(r) => SimpleNumber::Real(r.powi(p)),
526 }
527 }
528
529 pub fn div_euclid(&self, rhs: &Self) -> Self {
530 if rhs.is_positive() {
531 (self / rhs).to_integer(RoundingMode::Floor)
532 } else {
533 (self / rhs).to_integer(RoundingMode::Ceiling)
534 }
535 }
536
537 pub fn pow(&self, p: &SimpleNumber) -> Self {
538 if self.is_zero() {
539 if p.is_zero() {
540 if self.is_exact() && p.is_exact() {
541 return Self::from(1);
542 } else {
543 return Self::from(1.0);
544 }
545 } else if p.is_positive() {
546 if self.is_exact() && p.is_exact() {
547 return Self::from(0);
548 } else {
549 return Self::from(0.0);
550 }
551 } else {
552 return Self::infinity();
553 }
554 }
555 match (self, p) {
556 (SimpleNumber::FixedInteger(l), SimpleNumber::FixedInteger(r)) if *r >= 0 => {
557 SimpleNumber::from(Integer::from(*l).pow(*r as u64))
558 }
559 (SimpleNumber::FixedInteger(l), SimpleNumber::FixedInteger(r)) if *r < 0 => {
560 SimpleNumber::from(Rational::from_integers(
561 Integer::from(1),
562 Integer::from(*l).pow(-*r as u64),
563 ))
564 }
565 (SimpleNumber::FixedInteger(l), SimpleNumber::BigInteger(i)) if *i >= 0 => {
566 let exp: Option<u64> = i.try_into().ok();
567 if let Some(exp) = exp {
568 SimpleNumber::from(Integer::from(*l).pow(exp))
569 } else {
570 SimpleNumber::infinity()
571 }
572 }
573 (SimpleNumber::FixedInteger(l), SimpleNumber::BigInteger(i)) if *i < 0 => {
574 let exp: Option<u64> = (&(-i)).try_into().ok();
575 if let Some(exp) = exp {
576 SimpleNumber::from(Rational::from_integers(
577 Integer::from(1),
578 Integer::from(*l).pow(exp),
579 ))
580 } else {
581 SimpleNumber::zero()
582 }
583 }
584 (SimpleNumber::BigInteger(l), SimpleNumber::FixedInteger(r)) if *r >= 0 => {
585 SimpleNumber::from(l.pow(*r as u64))
586 }
587 (SimpleNumber::BigInteger(l), SimpleNumber::FixedInteger(r)) if *r < 0 => {
588 SimpleNumber::from(Rational::from_integers(Integer::from(1), l.pow(-*r as u64)))
589 }
590 (SimpleNumber::BigInteger(l), SimpleNumber::BigInteger(i)) if *i >= 0 => {
591 let exp: Option<u64> = i.try_into().ok();
592 if let Some(exp) = exp {
593 SimpleNumber::from(l.pow(exp))
594 } else {
595 SimpleNumber::infinity()
596 }
597 }
598 (SimpleNumber::BigInteger(l), SimpleNumber::BigInteger(i)) if *i < 0 => {
599 let exp: Option<u64> = (&(-i)).try_into().ok();
600 if let Some(exp) = exp {
601 SimpleNumber::from(Rational::from_integers(Integer::from(1), l.pow(exp)))
602 } else {
603 SimpleNumber::zero()
604 }
605 }
606 (SimpleNumber::Rational(r), SimpleNumber::FixedInteger(exp)) if *exp >= 0 => {
607 SimpleNumber::from(r.pow(*exp as u64))
608 }
609 (SimpleNumber::Rational(r), SimpleNumber::FixedInteger(exp)) if *exp < 0 => {
610 SimpleNumber::from((Rational::from(1) / r).pow(-exp as u64))
611 }
612 (l, r) => {
613 let l = l.to_f64();
614 let r = r.to_f64();
615 SimpleNumber::from(l.powf(r))
616 }
617 }
618 }
619
620 pub fn sqrt(&self) -> Self {
621 match self {
622 SimpleNumber::FixedInteger(i) => SimpleNumber::Real((*i as f64).sqrt()),
623 SimpleNumber::BigInteger(i) => {
624 SimpleNumber::Real(f64::rounding_from(i, RoundingMode::Nearest).0.sqrt())
625 }
626 SimpleNumber::Rational(r) => {
627 SimpleNumber::Real(f64::rounding_from(r, RoundingMode::Nearest).0.sqrt())
628 }
629 SimpleNumber::Real(r) => SimpleNumber::Real(r.sqrt()),
630 }
631 }
632
633 pub fn eqv(&self, rhs: &Self) -> bool {
636 (self.is_nan() && rhs.is_nan()) || (self.is_exact() == rhs.is_exact() && self == rhs)
637 }
638
639 pub fn to_f64(&self) -> f64 {
640 match self {
641 Self::FixedInteger(i) => *i as f64,
642 Self::BigInteger(i) => f64::rounding_from(i, RoundingMode::Nearest).0,
643 Self::Rational(r) => f64::rounding_from(r, RoundingMode::Nearest).0,
644 Self::Real(r) => *r,
645 }
646 }
647
648 pub fn exp(&self) -> Self {
649 Self::Real(self.to_f64().exp())
650 }
651
652 pub fn ln(&self) -> Self {
653 Self::Real(self.to_f64().ln())
654 }
655
656 pub fn sin(&self) -> Self {
657 Self::Real(self.to_f64().sin())
658 }
659
660 pub fn cos(&self) -> Self {
661 Self::Real(self.to_f64().cos())
662 }
663
664 pub fn tan(&self) -> Self {
665 Self::Real(self.to_f64().tan())
666 }
667
668 pub fn sinh(&self) -> Self {
669 Self::Real(self.to_f64().sinh())
670 }
671
672 pub fn cosh(&self) -> Self {
673 Self::Real(self.to_f64().cosh())
674 }
675
676 pub fn tanh(&self) -> Self {
677 Self::Real(self.to_f64().tanh())
678 }
679
680 pub fn asin(&self) -> Self {
681 Self::Real(self.to_f64().asin())
682 }
683
684 pub fn acos(&self) -> Self {
685 Self::Real(self.to_f64().acos())
686 }
687
688 pub fn atan(&self) -> Self {
689 Self::Real(self.to_f64().atan())
690 }
691
692 pub fn atan2(&self, num2: &Self) -> Self {
693 Self::Real(self.to_f64().atan2(num2.to_f64()))
694 }
695}
696
697impl From<&Number> for Option<SimpleNumber> {
698 fn from(value: &Number) -> Self {
699 match value.0.as_ref() {
700 NumberInner::Simple(simple) => Some(simple.clone()),
701 NumberInner::Complex(complex) if complex.im.is_exact() && complex.im.is_zero() => {
702 Some(complex.re.clone())
703 }
704 _ => None,
705 }
706 }
707}
708
709impl From<Number> for Option<SimpleNumber> {
710 fn from(value: Number) -> Self {
711 Self::from(&value)
712 }
713}
714
715impl TryFrom<&Number> for SimpleNumber {
716 type Error = Exception;
717
718 fn try_from(value: &Number) -> Result<Self, Self::Error> {
719 <Option<SimpleNumber> as From<&Number>>::from(value)
720 .ok_or_else(|| Exception::type_error("real?", "complex?"))
721 }
722}
723
724impl TryFrom<Number> for SimpleNumber {
725 type Error = Exception;
726
727 fn try_from(value: Number) -> Result<Self, Self::Error> {
728 <Option<SimpleNumber> as From<Number>>::from(value)
729 .ok_or_else(|| Exception::type_error("real?", "complex?"))
730 }
731}
732
733macro_rules! impl_from_int {
734 ($ty:ty) => {
735 impl From<$ty> for SimpleNumber {
736 fn from(i: $ty) -> Self {
737 SimpleNumber::FixedInteger(i as i64)
738 }
739 }
740 };
741}
742
743impl_from_int!(i8);
744impl_from_int!(i16);
745impl_from_int!(i32);
746impl_from_int!(i64);
747impl_from_int!(u8);
748impl_from_int!(u16);
749impl_from_int!(u32);
750impl_from_int!(u64);
751
752macro_rules! impl_from_large_int {
753 ($ty:ty) => {
754 impl From<$ty> for SimpleNumber {
755 fn from(u: $ty) -> Self {
756 match u.try_into() {
757 Ok(i) => SimpleNumber::FixedInteger(i),
758 Err(_) => SimpleNumber::BigInteger(Integer::from(u)),
759 }
760 }
761 }
762 };
763}
764
765impl_from_large_int!(i128);
766impl_from_large_int!(isize);
767impl_from_large_int!(u128);
768impl_from_large_int!(usize);
769
770impl From<Integer> for SimpleNumber {
771 fn from(i: Integer) -> Self {
772 Self::BigInteger(i)
773 }
774}
775
776impl From<Rational> for SimpleNumber {
777 fn from(r: Rational) -> Self {
778 Self::Rational(r)
779 }
780}
781
782impl From<f64> for SimpleNumber {
783 fn from(r: f64) -> Self {
784 Self::Real(r)
785 }
786}
787
788impl From<ComplexNumber> for Number {
789 fn from(complex: ComplexNumber) -> Self {
790 Self(Arc::new(NumberInner::Complex(complex)))
791 }
792}
793
794macro_rules! number_try_into_impl_integer {
795 ($ty:tt) => {
796 impl TryFrom<&SimpleNumber> for $ty {
797 type Error = Exception;
798
799 fn try_from(num: &SimpleNumber) -> Result<$ty, Self::Error> {
800 match num {
801 SimpleNumber::FixedInteger(i) => {
802 if size_of::<$ty>() > size_of::<u32>() {
806 Ok(*i as $ty)
807 } else if *i <= $ty::MAX as i64 && *i >= $ty::MIN as i64 {
808 Ok(*i as $ty)
809 } else {
810 Err(Exception::not_representable(
811 &format!("{i}"),
812 stringify!($ty),
813 ))
814 }
815 }
816 SimpleNumber::BigInteger(bigint) => $ty::convertible_from(bigint)
817 .then(|| $ty::wrapping_from(bigint))
818 .ok_or_else(|| {
819 Exception::not_representable(&format!("{bigint}"), stringify!($ty))
820 }),
821 SimpleNumber::Rational(_) => {
822 Err(Exception::conversion_error(stringify!($ty), "rational"))
823 }
824 SimpleNumber::Real(_) => {
825 Err(Exception::conversion_error(stringify!($ty), "real"))
826 }
827 }
828 }
829 }
830
831 impl TryFrom<SimpleNumber> for $ty {
832 type Error = Exception;
833
834 fn try_from(num: SimpleNumber) -> Result<$ty, Self::Error> {
835 $ty::try_from(&num)
836 }
837 }
838
839 impl From<&SimpleNumber> for Option<$ty> {
840 fn from(num: &SimpleNumber) -> Option<$ty> {
841 match num {
842 SimpleNumber::FixedInteger(i) => {
843 if size_of::<$ty>() > size_of::<u32>() {
844 Some(*i as $ty)
845 } else if *i <= $ty::MAX as i64 && *i >= $ty::MIN as i64 {
846 Some(*i as $ty)
847 } else {
848 None
849 }
850 }
851 SimpleNumber::BigInteger(bigint) => {
852 $ty::convertible_from(bigint).then(|| $ty::wrapping_from(bigint))
853 }
854 _ => None,
855 }
856 }
857 }
858
859 impl From<SimpleNumber> for Option<$ty> {
860 fn from(num: SimpleNumber) -> Option<$ty> {
861 Self::from(&num)
862 }
863 }
864 };
865}
866
867number_try_into_impl_integer!(u8);
868number_try_into_impl_integer!(u16);
869number_try_into_impl_integer!(u32);
870number_try_into_impl_integer!(u64);
871number_try_into_impl_integer!(u128);
872number_try_into_impl_integer!(usize);
873number_try_into_impl_integer!(i8);
874number_try_into_impl_integer!(i16);
875number_try_into_impl_integer!(i32);
876number_try_into_impl_integer!(i64);
877number_try_into_impl_integer!(i128);
878number_try_into_impl_integer!(isize);
879
880impl TryFrom<&SimpleNumber> for Integer {
881 type Error = Exception;
882
883 fn try_from(num: &SimpleNumber) -> Result<Integer, Self::Error> {
884 match num {
885 SimpleNumber::FixedInteger(i) => Ok(Integer::from(*i)),
886 SimpleNumber::BigInteger(i) => Ok(i.clone()),
887 SimpleNumber::Rational(r) if *r.denominator_ref() == 1u32 => {
888 Ok(Integer::from(r.to_numerator()))
889 }
890 SimpleNumber::Rational(_) => Err(Exception::conversion_error("integer", "rational")),
891 SimpleNumber::Real(r) if !r.is_nan() && !r.is_infinite() && r.fract() == 0.0 => {
892 Ok(Integer::rounding_from(*r, RoundingMode::Nearest).0)
893 }
894 SimpleNumber::Real(_) => Err(Exception::conversion_error("integer", "real")),
895 }
896 }
897}
898
899impl TryFrom<SimpleNumber> for Integer {
900 type Error = Exception;
901
902 fn try_from(num: SimpleNumber) -> Result<Integer, Self::Error> {
903 Integer::try_from(&num)
904 }
905}
906
907impl From<&SimpleNumber> for Option<Integer> {
908 fn from(num: &SimpleNumber) -> Option<Integer> {
909 match num {
910 SimpleNumber::FixedInteger(i) => Some(Integer::from(*i)),
911 SimpleNumber::BigInteger(i) => Some(i.clone()),
912 SimpleNumber::Rational(r) if *r.denominator_ref() == 1u32 => {
913 Some(Integer::from(r.to_numerator()))
914 }
915 SimpleNumber::Rational(_) => None,
916 SimpleNumber::Real(r) if !r.is_nan() && !r.is_infinite() && r.fract() == 0.0 => {
917 Some(Integer::rounding_from(*r, RoundingMode::Nearest).0)
918 }
919 SimpleNumber::Real(_) => None,
920 }
921 }
922}
923
924impl From<SimpleNumber> for Option<Integer> {
925 fn from(num: SimpleNumber) -> Option<Integer> {
926 Self::from(&num)
927 }
928}
929
930impl TryFrom<&SimpleNumber> for f64 {
931 type Error = Exception;
932
933 fn try_from(num: &SimpleNumber) -> Result<f64, Self::Error> {
934 match num {
935 SimpleNumber::FixedInteger(i) => Ok(*i as f64),
936 SimpleNumber::Real(r) => Ok(*r),
937 SimpleNumber::Rational(r) => {
938 if let Some((float, _, _)) =
939 r.sci_mantissa_and_exponent_round_ref(RoundingMode::Nearest)
940 {
941 Ok(float)
942 } else {
943 Err(Exception::not_representable(&format!("{r}"), "f64"))
944 }
945 }
946 SimpleNumber::BigInteger(_) => Err(Exception::conversion_error("f64", "integer")),
947 }
948 }
949}
950
951impl TryFrom<SimpleNumber> for f64 {
952 type Error = Exception;
953
954 fn try_from(num: SimpleNumber) -> Result<f64, Self::Error> {
955 f64::try_from(&num)
956 }
957}
958
959impl From<&SimpleNumber> for Option<f64> {
960 fn from(num: &SimpleNumber) -> Option<f64> {
961 match num {
962 SimpleNumber::FixedInteger(i) => Some(*i as f64),
963 SimpleNumber::Real(r) => Some(*r),
964 SimpleNumber::Rational(r) => r
965 .sci_mantissa_and_exponent_round_ref(RoundingMode::Nearest)
966 .map(|(float, _, _)| float),
967 SimpleNumber::BigInteger(_) => None,
968 }
969 }
970}
971
972impl From<SimpleNumber> for Option<f64> {
973 fn from(num: SimpleNumber) -> Option<f64> {
974 Self::from(&num)
975 }
976}
977
978impl TryFrom<&Number> for f64 {
979 type Error = Exception;
980
981 fn try_from(num: &Number) -> Result<f64, Self::Error> {
982 match num.0.as_ref() {
983 NumberInner::Simple(simple) => f64::try_from(simple),
984 NumberInner::Complex(complex) if !complex.im.is_exact() && complex.im.is_zero() => {
985 f64::try_from(&complex.re)
986 }
987 _ => Err(Exception::conversion_error("f64", "complex")),
988 }
989 }
990}
991
992impl TryFrom<Number> for f64 {
993 type Error = Exception;
994
995 fn try_from(num: Number) -> Result<f64, Self::Error> {
996 f64::try_from(&num)
997 }
998}
999
1000impl From<&Number> for Option<f64> {
1001 fn from(num: &Number) -> Option<f64> {
1002 match num.0.as_ref() {
1003 NumberInner::Simple(simple) => Self::from(simple),
1004 NumberInner::Complex(complex) if !complex.im.is_exact() && complex.im.is_zero() => {
1005 Self::from(&complex.re)
1006 }
1007 _ => None,
1008 }
1009 }
1010}
1011
1012impl From<Number> for Option<f64> {
1013 fn from(num: Number) -> Option<f64> {
1014 Self::from(&num)
1015 }
1016}
1017
1018impl fmt::Display for SimpleNumber {
1019 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1020 match self {
1021 Self::FixedInteger(i) => write!(f, "{i}"),
1022 Self::BigInteger(i) => write!(f, "{i}"),
1023 Self::Rational(r) => write!(f, "{r}"),
1024 Self::Real(r) if r.is_nan() => write!(f, "+nan.0"),
1025 Self::Real(r) if r.is_infinite() && r.is_sign_positive() => write!(f, "+inf.0"),
1026 Self::Real(r) if r.is_infinite() && r.is_sign_negative() => write!(f, "-inf.0"),
1027 Self::Real(r) => write!(f, "{r:?}"),
1028 }
1029 }
1030}
1031
1032impl fmt::Debug for SimpleNumber {
1033 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1034 match self {
1035 Self::FixedInteger(i) => write!(f, "{i}"),
1036 Self::BigInteger(i) => write!(f, "{i}"),
1037 Self::Rational(r) => write!(f, "{r}"),
1038 Self::Real(r) if r.is_nan() => write!(f, "+nan.0"),
1039 Self::Real(r) if r.is_infinite() && r.is_sign_positive() => write!(f, "+inf.0"),
1040 Self::Real(r) if r.is_infinite() && r.is_sign_negative() => write!(f, "-inf.0"),
1041 Self::Real(r) => write!(f, "{r:?}"),
1042 }
1043 }
1044}
1045
1046impl Hash for SimpleNumber {
1048 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1049 match self {
1050 SimpleNumber::FixedInteger(i) => {
1051 0u8.hash(state);
1052 i.hash(state);
1053 }
1054 SimpleNumber::BigInteger(i) => {
1055 if i64::convertible_from(i) {
1056 0u8.hash(state);
1057 i64::wrapping_from(i).hash(state)
1058 } else {
1059 1u8.hash(state);
1060 i.hash(state)
1061 }
1062 }
1063 SimpleNumber::Rational(r) => {
1064 if *r.denominator_ref() == 1u32 {
1065 let i = if *r < 0 {
1066 -Integer::from(r.numerator_ref())
1067 } else {
1068 Integer::from(r.numerator_ref())
1069 };
1070 if i64::convertible_from(&i) {
1071 0u8.hash(state);
1072 i64::wrapping_from(&i).hash(state)
1073 } else {
1074 1u8.hash(state);
1075 i.hash(state)
1076 }
1077 } else {
1078 2u8.hash(state);
1079 r.hash(state)
1080 }
1081 }
1082 SimpleNumber::Real(r) => {
1083 3u8.hash(state);
1084 if r.is_nan() {
1085 f64::NAN.to_bits().hash(state);
1087 } else {
1088 r.to_bits().hash(state);
1089 }
1090 }
1091 }
1092 }
1093}
1094
1095impl PartialEq for SimpleNumber {
1096 fn eq(&self, rhs: &Self) -> bool {
1097 match (self, rhs) {
1098 (Self::FixedInteger(l), Self::FixedInteger(r)) => l == r,
1099 (Self::BigInteger(l), Self::BigInteger(r)) => l == r,
1100 (Self::Rational(l), Self::Rational(r)) => l == r,
1101 (Self::Real(l), Self::Real(r)) => l == r,
1102
1103 (Self::BigInteger(big_int), Self::FixedInteger(fixed_int))
1104 | (Self::FixedInteger(fixed_int), Self::BigInteger(big_int)) => fixed_int == big_int,
1105
1106 (Self::Rational(rational), Self::FixedInteger(fixed_int))
1107 | (Self::FixedInteger(fixed_int), Self::Rational(rational)) => fixed_int == rational,
1108
1109 (Self::BigInteger(big_int), Self::Rational(rational))
1110 | (Self::Rational(rational), Self::BigInteger(big_int)) => big_int == rational,
1111
1112 (Self::BigInteger(big_int), Self::Real(float))
1113 | (Self::Real(float), Self::BigInteger(big_int)) => float == big_int,
1114
1115 (Self::Rational(rational), Self::Real(float))
1116 | (Self::Real(float), Self::Rational(rational)) => float == rational,
1117
1118 (Self::FixedInteger(_), Self::Real(float))
1119 | (Self::Real(float), Self::FixedInteger(_))
1120 if float.fract() != 0.0 =>
1121 {
1122 false
1123 }
1124 (Self::FixedInteger(fixed_int), Self::Real(float))
1125 | (Self::Real(float), Self::FixedInteger(fixed_int)) => {
1126 float.to_i64() == Some(*fixed_int)
1127 }
1128 }
1129 }
1130}
1131
1132impl PartialOrd for SimpleNumber {
1133 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1134 match (self, rhs) {
1135 (Self::FixedInteger(l), Self::FixedInteger(r)) => l.partial_cmp(r),
1136 (Self::FixedInteger(l), Self::BigInteger(r)) => l.partial_cmp(r),
1137 (Self::FixedInteger(l), Self::Rational(r)) => l.partial_cmp(r),
1138 (Self::BigInteger(l), Self::FixedInteger(r)) => l.partial_cmp(r),
1139 (Self::BigInteger(l), Self::BigInteger(r)) => l.partial_cmp(r),
1140 (Self::BigInteger(l), Self::Rational(r)) => l.partial_cmp(r),
1141 (Self::BigInteger(l), Self::Real(r)) => l.partial_cmp(r),
1142 (Self::Rational(l), Self::FixedInteger(r)) => l.partial_cmp(r),
1143 (Self::Rational(l), Self::BigInteger(r)) => l.partial_cmp(r),
1144 (Self::Rational(l), Self::Rational(r)) => l.partial_cmp(r),
1145 (Self::Rational(l), Self::Real(r)) => l.partial_cmp(r),
1146 (Self::Real(l), Self::BigInteger(r)) => l.partial_cmp(r),
1147 (Self::Real(l), Self::Rational(r)) => l.partial_cmp(r),
1148 (Self::Real(l), Self::Real(r)) => l.partial_cmp(r),
1149 (Self::FixedInteger(l), Self::Real(r)) => Integer::from(*l).partial_cmp(r),
1152 (Self::Real(l), Self::FixedInteger(r)) => l.partial_cmp(&Integer::from(*r)),
1153 }
1154 }
1155}
1156
1157impl Neg for SimpleNumber {
1158 type Output = SimpleNumber;
1159
1160 fn neg(self) -> Self {
1161 match self {
1162 Self::FixedInteger(i) => Self::FixedInteger(-i),
1163 Self::BigInteger(i) => Self::BigInteger(-i),
1164 Self::Rational(r) => Self::Rational(-r),
1165 Self::Real(r) => Self::Real(-r),
1166 }
1167 }
1168}
1169
1170impl Neg for &'_ SimpleNumber {
1171 type Output = SimpleNumber;
1172
1173 fn neg(self) -> SimpleNumber {
1174 match self {
1175 SimpleNumber::FixedInteger(i) => i.checked_neg().map_or_else(
1176 || SimpleNumber::BigInteger(-Integer::from(*i)),
1177 SimpleNumber::FixedInteger,
1178 ),
1179 SimpleNumber::BigInteger(i) => SimpleNumber::BigInteger(-i),
1180 SimpleNumber::Rational(r) => SimpleNumber::Rational(-r),
1181 SimpleNumber::Real(r) => SimpleNumber::Real(-r),
1182 }
1183 }
1184}
1185
1186macro_rules! impl_op_for_simple_numbers {
1187 ($trait:ident, $op:ident, $checked:ident) => {
1188 impl $trait for &SimpleNumber {
1189 type Output = SimpleNumber;
1190
1191 fn $op(self, rhs: &SimpleNumber) -> SimpleNumber {
1192 match (self, rhs) {
1193 (SimpleNumber::FixedInteger(l), SimpleNumber::FixedInteger(r)) => l
1194 .$checked(*r)
1195 .map(SimpleNumber::FixedInteger)
1196 .unwrap_or_else(|| {
1197 SimpleNumber::BigInteger(Integer::from(*l).$op(Integer::from(*r)))
1198 }),
1199 (SimpleNumber::BigInteger(l), SimpleNumber::BigInteger(r)) => {
1200 SimpleNumber::BigInteger(l.$op(r))
1201 }
1202 (SimpleNumber::Rational(l), SimpleNumber::Rational(r)) => {
1203 SimpleNumber::Rational(l.$op(r))
1204 }
1205 (SimpleNumber::Real(l), SimpleNumber::Real(r)) => SimpleNumber::Real(l.$op(r)),
1206 (SimpleNumber::BigInteger(l), SimpleNumber::FixedInteger(r)) => {
1207 i64::convertible_from(l)
1208 .then(|| i64::wrapping_from(l).$checked(*r))
1209 .flatten()
1210 .map(SimpleNumber::FixedInteger)
1211 .unwrap_or_else(|| SimpleNumber::BigInteger(l.$op(Integer::from(*r))))
1212 }
1213 (SimpleNumber::FixedInteger(l), SimpleNumber::BigInteger(r)) => {
1214 i64::convertible_from(r)
1215 .then(|| l.$checked(i64::wrapping_from(r)))
1216 .flatten()
1217 .map(SimpleNumber::FixedInteger)
1218 .unwrap_or_else(|| SimpleNumber::BigInteger(Integer::from(*l).$op(r)))
1219 }
1220 (SimpleNumber::Rational(l), SimpleNumber::FixedInteger(r)) => {
1221 SimpleNumber::Rational(l.$op(Rational::from(*r)))
1222 }
1223 (SimpleNumber::FixedInteger(l), SimpleNumber::Rational(r)) => {
1224 SimpleNumber::Rational(Rational::from(*l).$op(r))
1225 }
1226
1227 (SimpleNumber::Rational(l), SimpleNumber::BigInteger(r)) => {
1228 SimpleNumber::Rational(l.$op(Rational::from(r)))
1229 }
1230 (SimpleNumber::BigInteger(l), SimpleNumber::Rational(r)) => {
1231 SimpleNumber::Rational(Rational::from(l).$op(r))
1232 }
1233
1234 (SimpleNumber::BigInteger(l), SimpleNumber::Real(r)) => {
1235 SimpleNumber::Real(f64::rounding_from(l, RoundingMode::Nearest).0.$op(*r))
1236 }
1237 (SimpleNumber::Real(l), SimpleNumber::BigInteger(r)) => {
1238 SimpleNumber::Real(l.$op(f64::rounding_from(r, RoundingMode::Nearest).0))
1239 }
1240
1241 (SimpleNumber::Rational(l), SimpleNumber::Real(r)) => {
1242 SimpleNumber::Real(f64::rounding_from(l, RoundingMode::Nearest).0.$op(r))
1243 }
1244 (SimpleNumber::Real(l), SimpleNumber::Rational(r)) => {
1245 SimpleNumber::Real(l.$op(f64::rounding_from(r, RoundingMode::Nearest).0))
1246 }
1247
1248 (SimpleNumber::FixedInteger(l), SimpleNumber::Real(r)) => {
1249 SimpleNumber::Real((*l as f64).$op(r))
1250 }
1251
1252 (SimpleNumber::Real(l), SimpleNumber::FixedInteger(r)) => {
1253 SimpleNumber::Real(l.$op(*r as f64))
1254 }
1255 }
1256 }
1257 }
1258
1259 impl $trait for SimpleNumber {
1260 type Output = SimpleNumber;
1261
1262 fn $op(self, rhs: SimpleNumber) -> SimpleNumber {
1263 (&self).$op(&rhs)
1264 }
1265 }
1266 };
1267}
1268
1269impl_op_for_simple_numbers!(Add, add, checked_add);
1270impl_op_for_simple_numbers!(Sub, sub, checked_sub);
1271impl_op_for_simple_numbers!(Mul, mul, checked_mul);
1272impl Div for &SimpleNumber {
1275 type Output = SimpleNumber;
1276
1277 fn div(self, rhs: &SimpleNumber) -> SimpleNumber {
1278 match (self, rhs) {
1279 (SimpleNumber::FixedInteger(l), SimpleNumber::FixedInteger(r)) => {
1280 SimpleNumber::Rational(Rational::from(*l) / Rational::from(*r))
1281 }
1282 (SimpleNumber::BigInteger(l), SimpleNumber::BigInteger(r)) => {
1283 SimpleNumber::Rational(Rational::from_integers_ref(l, r))
1284 }
1285 (SimpleNumber::Rational(l), SimpleNumber::Rational(r)) => SimpleNumber::Rational(l / r),
1286 (SimpleNumber::Real(l), SimpleNumber::Real(r)) => SimpleNumber::Real(l / r),
1287
1288 (SimpleNumber::BigInteger(l), SimpleNumber::FixedInteger(r)) => {
1289 SimpleNumber::Rational(Rational::from(l) / Rational::from(*r))
1290 }
1291 (SimpleNumber::FixedInteger(l), SimpleNumber::BigInteger(r)) => {
1292 SimpleNumber::Rational(Rational::from(*l) / Rational::from(r))
1293 }
1294
1295 (SimpleNumber::Rational(l), SimpleNumber::FixedInteger(r)) => {
1296 SimpleNumber::Rational(l / Rational::from(*r))
1297 }
1298 (SimpleNumber::FixedInteger(l), SimpleNumber::Rational(r)) => {
1299 SimpleNumber::Rational(Rational::from(*l) / r)
1300 }
1301
1302 (SimpleNumber::BigInteger(l), SimpleNumber::Rational(r)) => {
1303 SimpleNumber::Rational(Rational::from(l) / r)
1304 }
1305 (SimpleNumber::Rational(l), SimpleNumber::BigInteger(r)) => {
1306 SimpleNumber::Rational(l / Rational::from(r))
1307 }
1308
1309 (SimpleNumber::BigInteger(l), SimpleNumber::Real(r)) => {
1310 SimpleNumber::Real(f64::rounding_from(l, RoundingMode::Nearest).0 / *r)
1311 }
1312 (SimpleNumber::Real(l), SimpleNumber::BigInteger(r)) => {
1313 SimpleNumber::Real(*l / f64::rounding_from(r, RoundingMode::Nearest).0)
1314 }
1315
1316 (SimpleNumber::Rational(l), SimpleNumber::Real(r)) => {
1317 SimpleNumber::Real(f64::rounding_from(l, RoundingMode::Nearest).0 / *r)
1318 }
1319 (SimpleNumber::Real(l), SimpleNumber::Rational(r)) => {
1320 SimpleNumber::Real(*l / f64::rounding_from(r, RoundingMode::Nearest).0)
1321 }
1322
1323 (SimpleNumber::FixedInteger(l), SimpleNumber::Real(r)) => {
1324 SimpleNumber::Real(*l as f64 / r)
1325 }
1326 (SimpleNumber::Real(l), SimpleNumber::FixedInteger(r)) => {
1327 SimpleNumber::Real(l / *r as f64)
1328 }
1329 }
1330 }
1331}
1332
1333impl Div for SimpleNumber {
1334 type Output = SimpleNumber;
1335
1336 fn div(self, rhs: SimpleNumber) -> SimpleNumber {
1337 &self / &rhs
1338 }
1339}
1340
1341impl Rem for &'_ SimpleNumber {
1342 type Output = SimpleNumber;
1343
1344 fn rem(self, rhs: &SimpleNumber) -> SimpleNumber {
1345 match (self, rhs) {
1346 (SimpleNumber::FixedInteger(l), SimpleNumber::FixedInteger(r)) => l
1347 .checked_rem(*r)
1348 .map(SimpleNumber::FixedInteger)
1349 .unwrap_or_else(|| {
1350 SimpleNumber::BigInteger(Integer::from(*l) % (Integer::from(*r)))
1351 }),
1352 (SimpleNumber::BigInteger(l), SimpleNumber::BigInteger(r)) => {
1353 SimpleNumber::BigInteger(l % r)
1354 }
1355 (SimpleNumber::Rational(l), SimpleNumber::Rational(r)) => {
1356 SimpleNumber::Rational(mod_rationals(l, r))
1357 }
1358 (SimpleNumber::Real(l), SimpleNumber::Real(r)) => SimpleNumber::Real(l % r),
1359 (SimpleNumber::BigInteger(l), SimpleNumber::FixedInteger(r)) => {
1360 i64::convertible_from(l)
1361 .then(|| i64::wrapping_from(l).checked_rem(*r))
1362 .flatten()
1363 .map(SimpleNumber::FixedInteger)
1364 .unwrap_or_else(|| SimpleNumber::BigInteger(l % Integer::from(*r)))
1365 }
1366 (SimpleNumber::FixedInteger(l), SimpleNumber::BigInteger(r)) => {
1367 i64::convertible_from(r)
1368 .then(|| l.checked_rem(i64::wrapping_from(r)))
1369 .flatten()
1370 .map(SimpleNumber::FixedInteger)
1371 .unwrap_or_else(|| SimpleNumber::BigInteger(Integer::from(*l) % r))
1372 }
1373 (SimpleNumber::Rational(l), SimpleNumber::FixedInteger(r)) => {
1374 SimpleNumber::Rational(mod_rationals(l, &Rational::from(*r)))
1375 }
1376 (SimpleNumber::FixedInteger(l), SimpleNumber::Rational(r)) => {
1377 SimpleNumber::Rational(mod_rationals(&Rational::from(*l), r))
1378 }
1379
1380 (SimpleNumber::Rational(l), SimpleNumber::BigInteger(r)) => {
1381 SimpleNumber::Rational(mod_rationals(l, &Rational::from(r)))
1382 }
1383 (SimpleNumber::BigInteger(l), SimpleNumber::Rational(r)) => {
1384 SimpleNumber::Rational(mod_rationals(&Rational::from(l), r))
1385 }
1386
1387 (SimpleNumber::BigInteger(l), SimpleNumber::Real(r)) => {
1388 SimpleNumber::Real(f64::rounding_from(l, RoundingMode::Nearest).0 % *r)
1389 }
1390 (SimpleNumber::Real(l), SimpleNumber::BigInteger(r)) => {
1391 SimpleNumber::Real(l % f64::rounding_from(r, RoundingMode::Nearest).0)
1392 }
1393
1394 (SimpleNumber::Rational(l), SimpleNumber::Real(r)) => {
1395 SimpleNumber::Real(f64::rounding_from(l, RoundingMode::Nearest).0 % r)
1396 }
1397 (SimpleNumber::Real(l), SimpleNumber::Rational(r)) => {
1398 SimpleNumber::Real(l % f64::rounding_from(r, RoundingMode::Nearest).0)
1399 }
1400
1401 (SimpleNumber::FixedInteger(l), SimpleNumber::Real(r)) => {
1402 SimpleNumber::Real((*l as f64) % r)
1403 }
1404
1405 (SimpleNumber::Real(l), SimpleNumber::FixedInteger(r)) => {
1406 SimpleNumber::Real(l % *r as f64)
1407 }
1408 }
1409 }
1410}
1411
1412fn mod_rationals(lhs: &Rational, rhs: &Rational) -> Rational {
1413 (lhs - rhs) * Rational::from(Integer::rounding_from(lhs / rhs, RoundingMode::Floor).0)
1414}
1415
1416impl Rem for SimpleNumber {
1417 type Output = SimpleNumber;
1418
1419 fn rem(self, rhs: SimpleNumber) -> SimpleNumber {
1420 (&self) % &rhs
1421 }
1422}
1423
1424#[derive(Clone)]
1426pub struct ComplexNumber {
1427 re: SimpleNumber,
1428 im: SimpleNumber,
1429}
1430
1431impl ComplexNumber {
1432 pub fn new(re: SimpleNumber, im: SimpleNumber) -> Self {
1433 Self { re, im }
1434 }
1435
1436 pub fn is_zero(&self) -> bool {
1437 self.re.is_zero() && self.im.is_zero()
1438 }
1439
1440 pub fn one() -> Self {
1441 Self {
1442 re: SimpleNumber::one(),
1443 im: SimpleNumber::zero(),
1444 }
1445 }
1446
1447 pub fn i() -> Self {
1448 Self {
1449 re: SimpleNumber::zero(),
1450 im: SimpleNumber::one(),
1451 }
1452 }
1453
1454 pub fn inexact(&self) -> Self {
1455 Self {
1456 re: self.re.inexact(),
1457 im: self.im.inexact(),
1458 }
1459 }
1460
1461 pub fn exact(&self) -> Self {
1462 Self {
1463 re: self.re.exact(),
1464 im: self.im.exact(),
1465 }
1466 }
1467
1468 pub fn to_string(&self, radix: u32, precision: Option<usize>) -> Option<String> {
1469 let mut output = self.re.to_string(radix, precision)?;
1470 if self.im.is_exact() && self.im.is_zero() {
1471 return Some(output);
1472 }
1473 if self.im.is_positive() && !self.im.is_nan() && !self.im.is_infinite() {
1474 output.push('+');
1475 }
1476 output.push_str(&self.im.to_string(radix, precision)?);
1477 output.push('i');
1478 Some(output)
1479 }
1480
1481 pub fn from_polar(r: SimpleNumber, theta: SimpleNumber) -> Self {
1482 Self::new(&r * &theta.cos(), &r * &theta.sin())
1483 }
1484
1485 pub fn to_polar(&self) -> (SimpleNumber, SimpleNumber) {
1486 (self.magnitude(), self.arg())
1487 }
1488
1489 pub fn magnitude(&self) -> SimpleNumber {
1490 self.magnitude2().sqrt()
1491 }
1492
1493 pub fn magnitude2(&self) -> SimpleNumber {
1494 self.re.powi(2) + self.im.powi(2)
1495 }
1496
1497 pub fn sqrt(&self) -> Self {
1498 if self.im.is_zero() {
1499 if self.re.is_positive() {
1500 Self::new(self.re.sqrt(), self.im.clone())
1501 } else if self.im.is_positive() {
1502 Self::new(SimpleNumber::zero(), (-&self.re).sqrt())
1503 } else {
1504 Self::new(SimpleNumber::zero(), -(-&self.re).sqrt())
1505 }
1506 } else if self.re.is_zero() {
1507 let x = (self.im.abs() / SimpleNumber::from(2)).sqrt();
1508 if self.im.is_positive() {
1509 Self::new(x.clone(), x)
1510 } else {
1511 Self::new(x.clone(), -x)
1512 }
1513 } else {
1514 let (r, theta) = self.to_polar();
1515 Self::from_polar(r.sqrt(), theta / SimpleNumber::from(2))
1516 }
1517 }
1518
1519 pub fn arg(&self) -> SimpleNumber {
1520 self.im.atan2(&self.re)
1521 }
1522
1523 pub fn exp(&self) -> Self {
1524 Self::from_polar(self.re.exp(), self.im.clone())
1525 }
1526
1527 pub fn ln(&self) -> Self {
1528 let (r, theta) = self.to_polar();
1529 Self::new(r.ln(), theta)
1530 }
1531
1532 pub fn powc(&self, exp: &Self) -> Self {
1533 if exp.is_zero() {
1534 return Self::one();
1535 }
1536 (exp * &self.ln()).exp()
1537 }
1538
1539 pub fn sin(&self) -> Self {
1540 Self::new(
1541 self.re.sin() * self.im.cosh(),
1542 self.re.cos() * self.im.sinh(),
1543 )
1544 }
1545
1546 pub fn cos(&self) -> Self {
1547 Self::new(
1548 self.re.cos() * self.im.cosh(),
1549 -self.re.sin() * self.im.sinh(),
1550 )
1551 }
1552
1553 pub fn tan(&self) -> Self {
1554 let scale = (&self.re + &self.re).cos() + (&self.im + &self.im).cosh();
1555 let re = &(&self.re + &self.re).sin() / &scale;
1556 let im = &(&self.im + &self.im).sinh() / &scale;
1557 Self::new(re, im)
1558 }
1559
1560 pub fn asin(&self) -> Self {
1561 -Self::i() * ((Self::one() - self * self).sqrt() + &Self::i() * self).ln()
1562 }
1563
1564 pub fn acos(&self) -> Self {
1565 -Self::i() * (&(Self::i() * (Self::one() - self * self).sqrt()) + self).ln()
1566 }
1567
1568 pub fn atan(&self) -> Self {
1569 if self.re.is_zero() && self.im.is_one() {
1570 Self::new(SimpleNumber::zero(), SimpleNumber::infinity())
1571 } else if self.re.is_zero() && self.im.is_neg_one() {
1572 Self::new(SimpleNumber::zero(), SimpleNumber::neg_infinity())
1573 } else {
1574 ((&(Self::one() + Self::i()) * self).ln() - (Self::one() - &Self::i() * self).ln())
1575 / ((Self::one() + Self::one()) * Self::i())
1576 }
1577 }
1578}
1579
1580impl From<&Number> for Option<ComplexNumber> {
1583 fn from(value: &Number) -> Self {
1584 match value.0.as_ref() {
1585 NumberInner::Simple(simple) => {
1586 Some(ComplexNumber::new(simple.clone(), SimpleNumber::zero()))
1587 }
1588 NumberInner::Complex(complex) => Some(complex.clone()),
1589 }
1590 }
1591}
1592
1593impl From<Number> for Option<ComplexNumber> {
1594 fn from(value: Number) -> Self {
1595 (&value).into()
1596 }
1597}
1598
1599impl TryFrom<&Number> for ComplexNumber {
1600 type Error = Exception;
1601
1602 fn try_from(value: &Number) -> Result<Self, Self::Error> {
1603 match value.0.as_ref() {
1604 NumberInner::Simple(simple) => {
1605 Ok(ComplexNumber::new(simple.clone(), SimpleNumber::zero()))
1606 }
1607 NumberInner::Complex(complex) => Ok(complex.clone()),
1608 }
1609 }
1610}
1611
1612impl TryFrom<Number> for ComplexNumber {
1613 type Error = Exception;
1614
1615 fn try_from(value: Number) -> Result<Self, Self::Error> {
1616 (&value).try_into()
1617 }
1618}
1619
1620impl From<SimpleNumber> for ComplexNumber {
1621 fn from(value: SimpleNumber) -> Self {
1622 Self {
1623 re: value,
1624 im: SimpleNumber::FixedInteger(0),
1625 }
1626 }
1627}
1628
1629impl PartialEq for ComplexNumber {
1630 fn eq(&self, rhs: &ComplexNumber) -> bool {
1631 self.re == rhs.re && self.im == rhs.im
1632 }
1633}
1634
1635impl Neg for ComplexNumber {
1636 type Output = ComplexNumber;
1637
1638 fn neg(self) -> ComplexNumber {
1639 Self {
1640 re: -self.re,
1641 im: -self.im,
1642 }
1643 }
1644}
1645
1646impl Neg for &ComplexNumber {
1647 type Output = ComplexNumber;
1648
1649 fn neg(self) -> ComplexNumber {
1650 ComplexNumber {
1651 re: -(&self.re),
1652 im: -(&self.im),
1653 }
1654 }
1655}
1656
1657impl Add<&ComplexNumber> for &ComplexNumber {
1658 type Output = ComplexNumber;
1659
1660 fn add(self, rhs: &ComplexNumber) -> ComplexNumber {
1661 ComplexNumber {
1662 re: (&self.re).add(&rhs.re),
1663 im: (&self.im).add(&rhs.im),
1664 }
1665 }
1666}
1667
1668impl Add<ComplexNumber> for ComplexNumber {
1669 type Output = ComplexNumber;
1670
1671 fn add(self, rhs: ComplexNumber) -> ComplexNumber {
1672 ComplexNumber {
1673 re: self.re.add(rhs.re),
1674 im: self.im.add(rhs.im),
1675 }
1676 }
1677}
1678
1679impl Sub<&ComplexNumber> for &ComplexNumber {
1680 type Output = ComplexNumber;
1681
1682 fn sub(self, rhs: &ComplexNumber) -> ComplexNumber {
1683 ComplexNumber {
1684 re: (&self.re).sub(&rhs.re),
1685 im: (&self.im).sub(&rhs.im),
1686 }
1687 }
1688}
1689
1690impl Sub<ComplexNumber> for ComplexNumber {
1691 type Output = ComplexNumber;
1692
1693 fn sub(self, rhs: ComplexNumber) -> ComplexNumber {
1694 ComplexNumber {
1695 re: self.re.sub(rhs.re),
1696 im: self.im.sub(rhs.im),
1697 }
1698 }
1699}
1700
1701impl Mul<&ComplexNumber> for &ComplexNumber {
1702 type Output = ComplexNumber;
1703
1704 fn mul(self, rhs: &ComplexNumber) -> ComplexNumber {
1705 let re = &self.re * &rhs.re - &self.im * &rhs.im;
1706 let im = &self.re * &rhs.im + &self.im * &rhs.re;
1707 ComplexNumber::new(re, im)
1708 }
1709}
1710
1711impl Mul<ComplexNumber> for ComplexNumber {
1712 type Output = ComplexNumber;
1713
1714 fn mul(self, rhs: ComplexNumber) -> ComplexNumber {
1715 (&self).mul(&rhs)
1716 }
1717}
1718
1719impl Div for &ComplexNumber {
1720 type Output = ComplexNumber;
1721
1722 fn div(self, rhs: &ComplexNumber) -> ComplexNumber {
1723 let norm_sqr = rhs.re.powi(2) + rhs.im.powi(2);
1724 let re = self.re.clone() * rhs.re.clone() + self.im.clone() * rhs.im.clone();
1725 let im = self.im.clone() * rhs.re.clone() - self.re.clone() * rhs.im.clone();
1726 ComplexNumber {
1727 re: re / norm_sqr.clone(),
1728 im: im / norm_sqr,
1729 }
1730 }
1731}
1732
1733impl Div for ComplexNumber {
1734 type Output = ComplexNumber;
1735
1736 fn div(self, rhs: ComplexNumber) -> ComplexNumber {
1737 &self / &rhs
1738 }
1739}
1740
1741impl fmt::Display for ComplexNumber {
1742 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1743 write!(f, "{}", self.re)?;
1744 if self.im.is_positive() && !self.im.is_nan() && !self.im.is_infinite() {
1745 write!(f, "+")?;
1746 }
1747 write!(f, "{}i", self.im)
1748 }
1749}
1750
1751impl fmt::Debug for ComplexNumber {
1752 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1753 write!(f, "{:?}", self.re)?;
1754 if self.im.is_positive() && !self.im.is_nan() && !self.im.is_infinite() {
1755 write!(f, "+")?;
1756 }
1757 write!(f, "{:?}i", self.im)
1758 }
1759}
1760
1761impl fmt::Display for Number {
1762 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1763 match self.0.as_ref() {
1764 NumberInner::Simple(simple) => write!(f, "{simple}"),
1765 NumberInner::Complex(complex) => write!(f, "{complex}"),
1766 }
1767 }
1768}
1769
1770impl fmt::Debug for Number {
1771 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1772 match self.0.as_ref() {
1773 NumberInner::Simple(simple) => write!(f, "{simple:?}"),
1774 NumberInner::Complex(complex) => write!(f, "{complex:?}"),
1775 }
1776 }
1777}
1778
1779impl Hash for Number {
1780 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1781 std::mem::discriminant(self.0.as_ref()).hash(state);
1782 match self.0.as_ref() {
1783 NumberInner::Simple(simple) => simple.hash(state),
1784 NumberInner::Complex(complex) => {
1785 complex.re.hash(state);
1786 complex.im.hash(state);
1787 }
1788 }
1789 }
1790}
1791
1792impl PartialEq for Number {
1793 fn eq(&self, rhs: &Self) -> bool {
1794 match (self.0.as_ref(), rhs.0.as_ref()) {
1795 (NumberInner::Simple(lhs), NumberInner::Simple(rhs)) => lhs.eq(rhs),
1796 (NumberInner::Complex(lhs), NumberInner::Simple(rhs)) if lhs.im.is_zero() => {
1797 lhs.re.eq(rhs)
1798 }
1799 (NumberInner::Simple(lhs), NumberInner::Complex(rhs)) if rhs.im.is_zero() => {
1800 lhs.eq(&rhs.re)
1801 }
1802 (NumberInner::Complex(lhs), NumberInner::Complex(rhs)) => lhs == rhs,
1803 _ => false,
1804 }
1805 }
1806}
1807
1808impl PartialOrd for Number {
1809 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1810 match (self.0.as_ref(), rhs.0.as_ref()) {
1811 (NumberInner::Simple(lhs), NumberInner::Simple(rhs)) => lhs.partial_cmp(rhs),
1812 (NumberInner::Complex(lhs), NumberInner::Simple(rhs)) if lhs.im.is_zero() => {
1813 lhs.re.partial_cmp(rhs)
1814 }
1815 (NumberInner::Simple(lhs), NumberInner::Complex(rhs)) if rhs.im.is_zero() => {
1816 lhs.partial_cmp(&rhs.re)
1817 }
1818 (NumberInner::Complex(lhs), NumberInner::Complex(rhs))
1819 if lhs.im.is_zero() && rhs.im.is_zero() =>
1820 {
1821 lhs.re.partial_cmp(&rhs.re)
1822 }
1823 _ => None,
1824 }
1825 }
1826}
1827
1828impl Neg for Number {
1829 type Output = Number;
1830
1831 fn neg(self) -> Self {
1832 match self.0.as_ref() {
1833 NumberInner::Simple(this) => Number::from(-this),
1834 NumberInner::Complex(this) => Number::from(-this),
1835 }
1836 }
1837}
1838
1839impl Neg for &'_ Number {
1840 type Output = Number;
1841
1842 fn neg(self) -> Number {
1843 match self.0.as_ref() {
1844 NumberInner::Simple(this) => Number::from(-this),
1845 NumberInner::Complex(this) => Number::from(-this),
1846 }
1847 }
1848}
1849
1850macro_rules! impl_op_for_number {
1851 ($trait:ident, $op:ident) => {
1852 impl $trait for &Number {
1853 type Output = Number;
1854
1855 fn $op(self, rhs: &Number) -> Self::Output {
1856 match (self.0.as_ref(), rhs.0.as_ref()) {
1857 (NumberInner::Simple(lhs), NumberInner::Simple(rhs)) => {
1858 Number::from(lhs.$op(rhs))
1859 }
1860 (NumberInner::Simple(lhs), NumberInner::Complex(rhs)) => {
1861 Number::from((&ComplexNumber::from(lhs.clone())).$op(rhs))
1862 }
1863 (NumberInner::Complex(lhs), NumberInner::Simple(rhs)) => {
1864 Number::from(lhs.$op(&ComplexNumber::from(rhs.clone())))
1865 }
1866 (NumberInner::Complex(lhs), NumberInner::Complex(rhs)) => {
1867 Number::from(lhs.$op(rhs))
1868 }
1869 }
1870 }
1871 }
1872
1873 impl $trait for Number {
1874 type Output = Number;
1875
1876 fn $op(self, rhs: Number) -> Self::Output {
1877 (&self).$op(&rhs)
1878 }
1879 }
1880 };
1881}
1882
1883impl_op_for_number!(Add, add);
1884impl_op_for_number!(Sub, sub);
1885impl_op_for_number!(Mul, mul);
1886impl_op_for_number!(Div, div);
1887
1888#[bridge(name = "number?", lib = "(rnrs base builtins (6))")]
1892pub fn is_number(arg: &Value) -> Result<Vec<Value>, Exception> {
1893 Ok(vec![Value::from(arg.type_of() == ValueType::Number)])
1894}
1895
1896#[bridge(name = "complex?", lib = "(rnrs base builtins (6))")]
1897pub fn is_complex(arg: &Value) -> Result<Vec<Value>, Exception> {
1898 Ok(vec![Value::from(
1899 arg.cast_to_scheme_type::<Number>()
1900 .as_ref()
1901 .is_some_and(Number::is_complex),
1902 )])
1903}
1904
1905#[bridge(name = "real?", lib = "(rnrs base builtins (6))")]
1906pub fn is_real(arg: &Value) -> Result<Vec<Value>, Exception> {
1907 Ok(vec![Value::from(
1908 arg.cast_to_scheme_type::<Number>()
1909 .as_ref()
1910 .is_some_and(Number::is_real),
1911 )])
1912}
1913
1914#[bridge(name = "rational?", lib = "(rnrs base builtins (6))")]
1915pub fn is_rational(arg: &Value) -> Result<Vec<Value>, Exception> {
1916 Ok(vec![Value::from(
1917 arg.cast_to_scheme_type::<Number>()
1918 .as_ref()
1919 .is_some_and(Number::is_rational),
1920 )])
1921}
1922
1923#[bridge(name = "integer?", lib = "(rnrs base builtins (6))")]
1924pub fn is_integer(arg: &Value) -> Result<Vec<Value>, Exception> {
1925 Ok(vec![Value::from(
1926 arg.cast_to_scheme_type::<Number>()
1927 .as_ref()
1928 .is_some_and(Number::is_integer),
1929 )])
1930}
1931
1932#[bridge(name = "real-valued?", lib = "(rnrs base builtins (6))")]
1933pub fn real_valued_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1934 Ok(vec![Value::from(
1935 arg.cast_to_scheme_type::<Number>()
1936 .as_ref()
1937 .is_some_and(Number::is_real_valued),
1938 )])
1939}
1940
1941#[bridge(name = "rational-valued?", lib = "(rnrs base builtins (6))")]
1942pub fn rational_valued_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1943 Ok(vec![Value::from(
1944 arg.cast_to_scheme_type::<Number>()
1945 .as_ref()
1946 .is_some_and(Number::is_rational_valued),
1947 )])
1948}
1949
1950#[bridge(name = "integer-valued?", lib = "(rnrs base builtins (6))")]
1951pub fn integer_valued_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1952 Ok(vec![Value::from(
1953 arg.cast_to_scheme_type::<Number>()
1954 .as_ref()
1955 .is_some_and(Number::is_integer_valued),
1956 )])
1957}
1958
1959#[bridge(name = "exact?", lib = "(rnrs base builtins (6))")]
1960pub fn exact_pred(z: Number) -> Result<Vec<Value>, Exception> {
1961 Ok(vec![Value::from(z.is_exact())])
1962}
1963
1964#[bridge(name = "inexact?", lib = "(rnrs base builtins (6))")]
1965pub fn inexact_pred(z: Number) -> Result<Vec<Value>, Exception> {
1966 Ok(vec![Value::from(z.is_inexact())])
1967}
1968
1969#[bridge(name = "inexact", lib = "(rnrs base builtins (6))")]
1970pub fn inexact(z: Number) -> Result<Vec<Value>, Exception> {
1971 Ok(vec![Value::from(z.inexact())])
1972}
1973
1974#[bridge(name = "exact", lib = "(rnrs base builtins (6))")]
1975pub fn exact(z: Number) -> Result<Vec<Value>, Exception> {
1976 Ok(vec![Value::from(z.exact())])
1977}
1978
1979#[bridge(name = "=", lib = "(rnrs base builtins (6))")]
1980pub fn equal(args: &[Value]) -> Result<Vec<Value>, Exception> {
1981 Ok(vec![Value::from(equal_prim(args)?)])
1982}
1983
1984pub(crate) fn equal_prim(vals: &[Value]) -> Result<bool, Exception> {
1985 if let Some((first, rest)) = vals.split_first() {
1986 let first: Number = first.try_to_scheme_type()?;
1987 for next in rest {
1988 let next: Number = next.try_to_scheme_type()?;
1989 if !(first == next) {
1990 return Ok(false);
1991 }
1992 }
1993 }
1994 Ok(true)
1995}
1996
1997#[bridge(name = "<", lib = "(rnrs base builtins (6))")]
1998pub fn lesser(args: &[Value]) -> Result<Vec<Value>, Exception> {
1999 Ok(vec![Value::from(lesser_prim(args)?)])
2000}
2001
2002pub(crate) fn lesser_prim(vals: &[Value]) -> Result<bool, Exception> {
2003 if let Some((head, rest)) = vals.split_first() {
2004 let mut prev = head.clone();
2005 for next in rest {
2006 let prev_num: Number = prev.try_to_scheme_type()?;
2007 let next_num: Number = next.try_to_scheme_type()?;
2008 if !prev_num.is_real() {
2009 return Err(Exception::type_error("real", "complex"));
2010 }
2011 if !next_num.is_real() {
2012 return Err(Exception::type_error("real", "complex"));
2013 }
2014 if !matches!(prev_num.partial_cmp(&next_num), Some(Ordering::Less)) {
2015 return Ok(false);
2016 }
2017 prev = next.clone();
2018 }
2019 }
2020 Ok(true)
2021}
2022
2023#[bridge(name = ">", lib = "(rnrs base builtins (6))")]
2024pub fn greater(args: &[Value]) -> Result<Vec<Value>, Exception> {
2025 Ok(vec![Value::from(greater_prim(args)?)])
2026}
2027
2028pub(crate) fn greater_prim(vals: &[Value]) -> Result<bool, Exception> {
2029 if let Some((head, rest)) = vals.split_first() {
2030 let mut prev = head.clone();
2031 for next in rest {
2032 let prev_num: Number = prev.try_to_scheme_type()?;
2033 let next_num: Number = next.try_to_scheme_type()?;
2034 if !prev_num.is_real() {
2037 return Err(Exception::type_error("real", "complex"));
2038 }
2039 if !next_num.is_real() {
2040 return Err(Exception::type_error("real", "complex"));
2041 }
2042 if !matches!(prev_num.partial_cmp(&next_num), Some(Ordering::Greater)) {
2043 return Ok(false);
2044 }
2045 prev = next.clone();
2046 }
2047 }
2048 Ok(true)
2049}
2050
2051#[bridge(name = "<=", lib = "(rnrs base builtins (6))")]
2052pub fn lesser_equal(args: &[Value]) -> Result<Vec<Value>, Exception> {
2053 Ok(vec![Value::from(lesser_equal_prim(args)?)])
2054}
2055
2056pub(crate) fn lesser_equal_prim(vals: &[Value]) -> Result<bool, Exception> {
2057 if let Some((head, rest)) = vals.split_first() {
2058 let mut prev = head.clone();
2059 for next in rest {
2060 let prev_num: Number = prev.try_to_scheme_type()?;
2061 let next_num: Number = next.try_to_scheme_type()?;
2062 if !prev_num.is_real() {
2063 return Err(Exception::type_error("real", "complex"));
2064 }
2065 if !next_num.is_real() {
2066 return Err(Exception::type_error("real", "complex"));
2067 }
2068 if !matches!(
2069 prev_num.partial_cmp(&next_num),
2070 Some(Ordering::Equal | Ordering::Less)
2071 ) {
2072 return Ok(false);
2073 }
2074 prev = next.clone();
2075 }
2076 }
2077 Ok(true)
2078}
2079
2080#[bridge(name = ">=", lib = "(rnrs base builtins (6))")]
2081pub fn greater_equal(args: &[Value]) -> Result<Vec<Value>, Exception> {
2082 Ok(vec![Value::from(greater_equal_prim(args)?)])
2083}
2084
2085pub(crate) fn greater_equal_prim(vals: &[Value]) -> Result<bool, Exception> {
2086 if let Some((head, rest)) = vals.split_first() {
2087 let mut prev = head.clone();
2088 for next in rest {
2089 let prev_num: Number = prev.try_to_scheme_type()?;
2090 let next_num: Number = next.try_to_scheme_type()?;
2091 if !prev_num.is_real() {
2092 return Err(Exception::type_error("real", "complex"));
2093 }
2094 if !next_num.is_real() {
2095 return Err(Exception::type_error("real", "complex"));
2096 }
2097 if !matches!(
2098 prev_num.partial_cmp(&next_num),
2099 Some(Ordering::Equal | Ordering::Greater)
2100 ) {
2101 return Ok(false);
2102 }
2103 prev = next.clone();
2104 }
2105 }
2106 Ok(true)
2107}
2108
2109#[bridge(name = "zero?", lib = "(rnrs base builtins (6))")]
2110pub fn zero(arg: &Value) -> Result<Vec<Value>, Exception> {
2111 let num: Number = arg.try_to_scheme_type()?;
2112 Ok(vec![Value::from(num.is_zero())])
2113}
2114
2115#[bridge(name = "odd?", lib = "(rnrs base builtins (6))")]
2116pub fn odd(arg: &Value) -> Result<Vec<Value>, Exception> {
2117 let int: Integer = arg.try_to_scheme_type()?;
2118 Ok(vec![Value::from(int.odd())])
2119}
2120
2121#[bridge(name = "even?", lib = "(rnrs base builtins (6))")]
2122pub fn even(arg: &Value) -> Result<Vec<Value>, Exception> {
2123 let int: Integer = arg.try_to_scheme_type()?;
2124 Ok(vec![Value::from(int.even())])
2125}
2126
2127#[bridge(name = "finite?", lib = "(rnrs base builtins (6))")]
2128pub fn is_finite(arg: &Value) -> Result<Vec<Value>, Exception> {
2129 Ok(vec![Value::from(
2130 !arg.try_to_scheme_type::<SimpleNumber>()?.is_infinite(),
2131 )])
2132}
2133
2134#[bridge(name = "infinite?", lib = "(rnrs base builtins (6))")]
2135pub fn is_infinite(arg: &Value) -> Result<Vec<Value>, Exception> {
2136 Ok(vec![Value::from(
2137 arg.try_to_scheme_type::<SimpleNumber>()?.is_infinite(),
2138 )])
2139}
2140
2141#[bridge(name = "nan?", lib = "(rnrs base builtins (6))")]
2142pub fn is_nan(arg: &Value) -> Result<Vec<Value>, Exception> {
2143 Ok(vec![Value::from(
2144 arg.try_to_scheme_type::<SimpleNumber>()?.is_nan(),
2145 )])
2146}
2147
2148#[bridge(name = "+", lib = "(rnrs base builtins (6))")]
2149pub fn add(args: &[Value]) -> Result<Vec<Value>, Exception> {
2150 Ok(vec![Value::from(add_prim(args)?)])
2151}
2152
2153pub(crate) fn add_prim(vals: &[Value]) -> Result<Number, Exception> {
2154 let mut result = Number::from(0i64);
2155 for val in vals {
2156 let num: Number = val.try_to_scheme_type()?;
2157 result = result + num;
2158 }
2159 Ok(result)
2160}
2161
2162#[bridge(name = "*", lib = "(rnrs base builtins (6))")]
2163pub fn mul(args: &[Value]) -> Result<Vec<Value>, Exception> {
2164 Ok(vec![Value::from(mul_prim(args)?)])
2165}
2166
2167pub(crate) fn mul_prim(vals: &[Value]) -> Result<Number, Exception> {
2168 let mut result = Number::from(1i64);
2169 for val in vals {
2170 let num: Number = val.try_to_scheme_type()?;
2171 result = result * num;
2172 }
2173 Ok(result)
2174}
2175
2176#[bridge(name = "-", lib = "(rnrs base builtins (6))")]
2177pub fn sub(arg1: &Value, args: &[Value]) -> Result<Vec<Value>, Exception> {
2178 Ok(vec![Value::from(sub_prim(arg1, args)?)])
2179}
2180
2181pub(crate) fn sub_prim(val1: &Value, vals: &[Value]) -> Result<Number, Exception> {
2182 let val1: Number = val1.try_to_scheme_type()?;
2183 let mut val1 = val1.clone();
2184 if vals.is_empty() {
2185 Ok(-val1)
2186 } else {
2187 for val in vals {
2188 let num: Number = val.try_to_scheme_type()?;
2189 val1 = val1 - num;
2190 }
2191 Ok(val1)
2192 }
2193}
2194
2195#[bridge(name = "/", lib = "(rnrs base builtins (6))")]
2196pub fn div(arg1: &Value, args: &[Value]) -> Result<Vec<Value>, Exception> {
2197 Ok(vec![Value::from(div_prim(arg1, args)?)])
2198}
2199
2200pub(crate) fn div_prim(val1: &Value, vals: &[Value]) -> Result<Number, Exception> {
2201 let mut is_exact = true;
2202 let val1: Number = val1.try_to_scheme_type()?;
2203 is_exact &= val1.is_exact();
2204 if vals.is_empty() {
2205 if val1.is_zero() && is_exact {
2206 return Err(Exception::error("division by zero"));
2207 } else {
2208 return Ok(Number::from(1) / val1);
2209 }
2210 }
2211 let mut result = val1.clone();
2212 for val in vals {
2213 let num: Number = val.try_to_scheme_type()?;
2214 is_exact &= num.is_exact();
2215 if num.is_zero() && is_exact {
2216 return Err(Exception::error("division by zero"));
2217 }
2218 result = result / num;
2219 }
2220 Ok(result)
2221}
2222
2223#[bridge(name = "div-and-mod", lib = "(rnrs base builtins (6))")]
2224pub fn div_mod(x1: SimpleNumber, x2: SimpleNumber) -> Result<Vec<Value>, Exception> {
2225 if x2.is_zero() {
2226 return Err(Exception::error("division by zero"));
2227 }
2228 let nd = x1.div_euclid(&x2);
2229 let nd_x2 = &x2 * &nd;
2230 let modulo = if nd_x2 < x1 { x1 - nd_x2 } else { nd_x2 - x1 };
2231 Ok(vec![Value::from(nd), Value::from(modulo)])
2232}
2233
2234#[bridge(name = "div", lib = "(rnrs base builtins (6))")]
2235pub fn integer_division(x1: SimpleNumber, x2: SimpleNumber) -> Result<Vec<Value>, Exception> {
2236 if x2.is_zero() {
2237 return Err(Exception::error("division by zero"));
2238 }
2239 let nd = x1.div_euclid(&x2);
2240 Ok(vec![Value::from(nd)])
2241}
2242
2243#[bridge(name = "mod", lib = "(rnrs base builtins (6))")]
2244pub fn modulo(x1: SimpleNumber, x2: SimpleNumber) -> Result<Vec<Value>, Exception> {
2245 if x2.is_zero() {
2246 return Err(Exception::error("modulo by zero"));
2247 }
2248 let nd = x1.div_euclid(&x2);
2249 let nd_x2 = &x2 * &nd;
2250 if nd_x2 < x1 {
2251 Ok(vec![Value::from(x1 - nd_x2)])
2252 } else {
2253 Ok(vec![Value::from(nd_x2 - x1)])
2254 }
2255}
2256
2257#[bridge(name = "numerator", lib = "(rnrs base builtins (6))")]
2258pub fn numerator(obj: &Value) -> Result<Vec<Value>, Exception> {
2259 match obj.try_to_scheme_type::<SimpleNumber>()? {
2260 SimpleNumber::Rational(r) => Ok(vec![Value::from(Integer::from_sign_and_abs(
2261 r >= 0i64,
2262 r.into_numerator(),
2263 ))]),
2264 _ => Ok(vec![obj.clone()]),
2265 }
2266}
2267
2268#[bridge(name = "denominator", lib = "(rnrs base builtins (6))")]
2269pub fn denominator(obj: &Value) -> Result<Vec<Value>, Exception> {
2270 match obj.try_to_scheme_type::<SimpleNumber>()? {
2271 SimpleNumber::Rational(r) => Ok(vec![Value::from(Integer::from(r.into_denominator()))]),
2272 SimpleNumber::Real(r) => Ok(vec![Value::from(
2273 f64::rounding_from(
2274 &Rational::try_from_float_simplest(r)
2275 .map_err(|_| Exception::error("not a rational"))?
2276 .into_denominator(),
2277 RoundingMode::Nearest,
2278 )
2279 .0,
2280 )]),
2281 _ => Ok(vec![Value::from(1)]),
2282 }
2283}
2284
2285#[bridge(name = "floor", lib = "(rnrs base builtins (6))")]
2286pub fn floor(obj: &Value) -> Result<Vec<Value>, Exception> {
2287 match obj.try_to_scheme_type::<SimpleNumber>()? {
2288 SimpleNumber::Rational(r) => Ok(vec![Value::from(
2289 Integer::rounding_from(r, RoundingMode::Floor).0,
2290 )]),
2291 SimpleNumber::Real(r) => Ok(vec![Value::from(r.floor())]),
2292 _ => Ok(vec![obj.clone()]),
2293 }
2294}
2295
2296#[bridge(name = "ceiling", lib = "(rnrs base builtins (6))")]
2297pub fn ceiling(obj: &Value) -> Result<Vec<Value>, Exception> {
2298 match obj.try_to_scheme_type::<SimpleNumber>()? {
2299 SimpleNumber::Rational(r) => Ok(vec![Value::from(
2300 Integer::rounding_from(r, RoundingMode::Ceiling).0,
2301 )]),
2302 SimpleNumber::Real(r) => Ok(vec![Value::from(r.ceil())]),
2303 _ => Ok(vec![obj.clone()]),
2304 }
2305}
2306
2307#[bridge(name = "truncate", lib = "(rnrs base builtins (6))")]
2308pub fn truncate(obj: &Value) -> Result<Vec<Value>, Exception> {
2309 match obj.try_to_scheme_type::<SimpleNumber>()? {
2310 SimpleNumber::Rational(r) => Ok(vec![Value::from(
2311 Integer::rounding_from(r, RoundingMode::Down).0,
2312 )]),
2313 SimpleNumber::Real(r) => Ok(vec![Value::from(r.trunc())]),
2314 _ => Ok(vec![obj.clone()]),
2315 }
2316}
2317
2318#[bridge(name = "round", lib = "(rnrs base builtins (6))")]
2319pub fn round(obj: &Value) -> Result<Vec<Value>, Exception> {
2320 match obj.try_to_scheme_type::<SimpleNumber>()? {
2321 SimpleNumber::Rational(r) => Ok(vec![Value::from(
2322 Integer::rounding_from(r, RoundingMode::Nearest).0,
2323 )]),
2324 SimpleNumber::Real(r) => Ok(vec![Value::from(r.round_ties_even())]),
2325 _ => Ok(vec![obj.clone()]),
2326 }
2327}
2328
2329#[bridge(name = "exp", lib = "(rnrs base builtins (6))")]
2330pub fn exp(z: &Value) -> Result<Vec<Value>, Exception> {
2331 Ok(vec![Value::from(z.try_to_scheme_type::<Number>()?.exp())])
2332}
2333
2334#[bridge(name = "log", lib = "(rnrs base builtins (6))")]
2335pub fn log(z: &Value, base: &[Value]) -> Result<Vec<Value>, Exception> {
2336 let base = match base {
2337 [] => None,
2338 [base] => Some(base.try_to_scheme_type::<f64>()?),
2339 _ => return Err(Exception::error("too many arguments")),
2340 };
2341 let num = match z.try_to_scheme_type::<SimpleNumber>()? {
2342 SimpleNumber::FixedInteger(i) => i as f64,
2343 SimpleNumber::BigInteger(i) => f64::rounding_from(&i, RoundingMode::Nearest).0,
2344 SimpleNumber::Rational(r) => f64::rounding_from(&r, RoundingMode::Nearest).0,
2345 SimpleNumber::Real(r) => r,
2346 };
2347 if let Some(base) = base {
2348 Ok(vec![Value::from(num.log(base))])
2349 } else {
2350 Ok(vec![Value::from(num.ln())])
2351 }
2352}
2353
2354#[bridge(name = "sin", lib = "(rnrs base builtins (6))")]
2355pub fn sin(z: Number) -> Result<Vec<Value>, Exception> {
2356 Ok(vec![Value::from(z.sin())])
2357}
2358
2359#[bridge(name = "cos", lib = "(rnrs base builtins (6))")]
2360pub fn cos(z: Number) -> Result<Vec<Value>, Exception> {
2361 Ok(vec![Value::from(z.cos())])
2362}
2363
2364#[bridge(name = "tan", lib = "(rnrs base builtins (6))")]
2365pub fn tan(z: Number) -> Result<Vec<Value>, Exception> {
2366 Ok(vec![Value::from(z.tan())])
2367}
2368
2369#[bridge(name = "asin", lib = "(rnrs base builtins (6))")]
2370pub fn asin(z: Number) -> Result<Vec<Value>, Exception> {
2371 Ok(vec![Value::from(z.asin())])
2372}
2373
2374#[bridge(name = "acos", lib = "(rnrs base builtins (6))")]
2375pub fn acos(z: Number) -> Result<Vec<Value>, Exception> {
2376 Ok(vec![Value::from(z.acos())])
2377}
2378
2379#[bridge(name = "atan", lib = "(rnrs base builtins (6))")]
2380pub fn atan(z: Number) -> Result<Vec<Value>, Exception> {
2381 Ok(vec![Value::from(z.atan())])
2382}
2383
2384#[bridge(name = "sqrt", lib = "(rnrs base builtins (6))")]
2385pub fn sqrt(z: &Value) -> Result<Vec<Value>, Exception> {
2386 Ok(vec![Value::from(z.try_to_scheme_type::<Number>()?.sqrt())])
2387}
2388
2389#[bridge(name = "exact-integer-sqrt", lib = "(rnrs base builtins (6))")]
2390pub fn exact_integer_sqrt(arg: Integer) -> Result<Vec<Value>, Exception> {
2391 let s = (&arg).floor_sqrt();
2392 let r = arg - &s * &s;
2393 Ok(vec![Value::from(s), Value::from(r)])
2394}
2395
2396#[bridge(name = "expt", lib = "(rnrs base builtins (6))")]
2397pub fn expt(z1: &Value, z2: &Value) -> Result<Vec<Value>, Exception> {
2398 let z1 = z1.try_to_scheme_type::<Number>()?;
2399 let z2 = z2.try_to_scheme_type::<Number>()?;
2400 Ok(vec![Value::from(z1.pow(&z2))])
2401}
2402
2403#[bridge(name = "make-rectangular", lib = "(rnrs base builtins (6))")]
2404pub fn make_rectangular(x1: SimpleNumber, x2: SimpleNumber) -> Result<Vec<Value>, Exception> {
2405 Ok(vec![Value::from(ComplexNumber::new(x1, x2))])
2406}
2407
2408#[bridge(name = "make-polar", lib = "(rnrs base builtins (6))")]
2409pub fn make_polar(x1: SimpleNumber, x2: SimpleNumber) -> Result<Vec<Value>, Exception> {
2410 Ok(vec![Value::from(ComplexNumber::from_polar(x1, x2))])
2411}
2412
2413#[bridge(name = "real-part", lib = "(rnrs base builtins (6))")]
2414pub fn real_part(arg: &Value) -> Result<Vec<Value>, Exception> {
2415 let num: Number = arg.try_to_scheme_type()?;
2416 if let Some(complex) = num.as_complex() {
2417 Ok(vec![Value::from(complex.re.clone())])
2418 } else {
2419 Ok(vec![arg.clone()])
2420 }
2421}
2422
2423#[bridge(name = "imag-part", lib = "(rnrs base builtins (6))")]
2424pub fn imag_part(arg: &Value) -> Result<Vec<Value>, Exception> {
2425 let num: Number = arg.try_to_scheme_type()?;
2426 if let Some(complex) = num.as_complex() {
2427 Ok(vec![Value::from(complex.im.clone())])
2428 } else {
2429 Err(Exception::error("expected complex number"))
2430 }
2431}
2432
2433#[bridge(name = "magnitude", lib = "(rnrs base builtins (6))")]
2434pub fn magnitude(arg: &Value) -> Result<Vec<Value>, Exception> {
2435 let num: Number = arg.try_to_scheme_type()?;
2436 if let Some(complex) = num.as_complex() {
2437 Ok(vec![Value::from(complex.magnitude())])
2438 } else {
2439 Ok(vec![arg.clone()])
2440 }
2441}
2442
2443#[bridge(name = "angle", lib = "(rnrs base builtins (6))")]
2444pub fn angle(z: ComplexNumber) -> Result<Vec<Value>, Exception> {
2445 let (_, angle) = z.to_polar();
2446 Ok(vec![Value::from(angle)])
2447}
2448
2449#[bridge(name = "number->string", lib = "(rnrs base builtins (6))")]
2450pub fn number_to_string(z: ComplexNumber, rest_args: &[Value]) -> Result<Vec<Value>, Exception> {
2451 let (radix, precision) = match rest_args {
2452 [] => (10, None),
2453 [radix] => (radix.try_to_scheme_type::<u32>()?, None),
2454 [radix, precision] => (
2455 radix.try_to_scheme_type::<u32>()?,
2456 Some(precision.try_to_scheme_type::<usize>()?),
2457 ),
2458 _ => return Err(Exception::wrong_num_of_var_args(2..3, 1 + rest_args.len())),
2459 };
2460 if !matches!(radix, 2 | 8 | 10 | 16) {
2461 return Err(Exception::error(format!(
2462 "invalid radix ({radix}) must be 2, 8, 10 or 16"
2463 )));
2464 }
2465 let result = z.to_string(radix, precision).ok_or_else(|| {
2466 Exception::implementation_restriction(format!("could not format {z} with radix {radix}"))
2467 })?;
2468 Ok(vec![Value::from(result)])
2469}
2470
2471#[maybe_async]
2472#[bridge(name = "string->number", lib = "(rnrs base builtins (6))")]
2473pub fn string_to_number(s: WideString, rest_args: &[Value]) -> Result<Vec<Value>, Exception> {
2474 let radix = match rest_args {
2475 [] => 10,
2476 [radix] => match radix.try_to_scheme_type::<u32>()? {
2477 radix @ (2 | 8 | 10 | 16) => radix,
2478 radix => {
2479 return Err(Exception::error(format!(
2480 "invalid radix ({radix}) must be 2, 8, 10 or 16"
2481 )));
2482 }
2483 },
2484 _ => return Err(Exception::wrong_num_of_var_args(1..2, 1 + rest_args.len())),
2485 };
2486 let s = s.to_string();
2488 let bytes = Cursor::new(s.as_bytes().to_vec());
2489 let port = Port::new("", bytes, BufferMode::Block, Some(Transcoder::native()));
2490 let info = &port.0.info;
2491 #[cfg(not(feature = "async"))]
2492 let mut data = port.0.data.lock().unwrap();
2493 #[cfg(feature = "tokio")]
2494 let mut data = port.0.data.lock().await;
2495 let mut lexer = Lexer::new(&mut data, info, Span::default());
2496 let Some(number) = maybe_await!(lexer.number(radix)).ok().flatten() else {
2497 return Ok(vec![Value::from(false)]);
2498 };
2499
2500 if maybe_await!(lexer.take()).ok().flatten().is_some() {
2501 return Ok(vec![Value::from(false)]);
2502 }
2503
2504 let Ok(number) = Number::try_from(number) else {
2505 return Ok(vec![Value::from(false)]);
2506 };
2507
2508 Ok(vec![Value::from(number)])
2509}
2510
2511pub struct Fixnum(pub i64);
2513
2514impl From<&Value> for Option<Fixnum> {
2515 fn from(value: &Value) -> Option<Fixnum> {
2516 if let Some(num) = value.cast_to_scheme_type::<Number>()
2517 && let NumberInner::Simple(simple) = &*num.0
2518 && let SimpleNumber::FixedInteger(fixnum) = simple
2519 {
2520 Some(Fixnum(*fixnum))
2521 } else {
2522 None
2523 }
2524 }
2525}
2526
2527impl TryFrom<&Value> for Fixnum {
2528 type Error = Exception;
2529
2530 fn try_from(value: &Value) -> Result<Self, Self::Error> {
2531 if let Some(num) = value.cast_to_scheme_type::<Number>()
2532 && let NumberInner::Simple(simple) = &*num.0
2533 && let SimpleNumber::FixedInteger(fixnum) = simple
2534 {
2535 Ok(Fixnum(*fixnum))
2536 } else {
2537 Err(Exception::error("value is not a fixnum"))
2538 }
2539 }
2540}
2541
2542#[bridge(name = "fixnum?", lib = "(rnrs arithmetic fixnums (6))")]
2543pub fn fixnum_pred(obj: &Value) -> Result<Vec<Value>, Exception> {
2544 Ok(vec![Value::from(
2545 obj.cast_to_scheme_type::<Fixnum>().is_some(),
2546 )])
2547}
2548
2549#[bridge(name = "fixnum-width", lib = "(rnrs arithmetic fixnums (6))")]
2550pub fn fixnum_width() -> Result<Vec<Value>, Exception> {
2551 Ok(vec![Value::from(64)])
2552}
2553
2554#[bridge(name = "least-fixnum", lib = "(rnrs arithmetic fixnums (6))")]
2555pub fn least_fixnum() -> Result<Vec<Value>, Exception> {
2556 Ok(vec![Value::from(i64::MIN)])
2557}
2558
2559#[bridge(name = "greatest-fixnum", lib = "(rnrs arithmetic fixnums (6))")]
2560pub fn greatest_fixnum() -> Result<Vec<Value>, Exception> {
2561 Ok(vec![Value::from(i64::MAX)])
2562}
2563
2564pub struct Flonum(pub f64);
2566
2567impl From<&Value> for Option<Flonum> {
2568 fn from(value: &Value) -> Option<Flonum> {
2569 if let Some(num) = value.cast_to_scheme_type::<Number>()
2570 && let NumberInner::Simple(simple) = &*num.0
2571 && let SimpleNumber::Real(flonum) = simple
2572 {
2573 Some(Flonum(*flonum))
2574 } else {
2575 None
2576 }
2577 }
2578}
2579
2580impl TryFrom<&Value> for Flonum {
2581 type Error = Exception;
2582
2583 fn try_from(value: &Value) -> Result<Self, Self::Error> {
2584 if let Some(num) = value.cast_to_scheme_type::<Number>()
2585 && let NumberInner::Simple(simple) = &*num.0
2586 && let SimpleNumber::Real(flonum) = simple
2587 {
2588 Ok(Flonum(*flonum))
2589 } else {
2590 Err(Exception::error("value is not a flonum"))
2591 }
2592 }
2593}
2594
2595#[bridge(name = "flonum?", lib = "(rnrs arithmetic flonums (6))")]
2596pub fn flonum_pred(obj: &Value) -> Result<Vec<Value>, Exception> {
2597 Ok(vec![Value::from(
2598 obj.cast_to_scheme_type::<Flonum>().is_some(),
2599 )])
2600}