1use num::bigint::BigInt;
2use num::traits::FloatConst;
3use num::{
4 BigRational, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Rational64, Signed,
5};
6use num::{Num, Rational32, ToPrimitive};
7use std::cmp::Ordering;
8use std::fmt;
9use std::fmt::{Binary, Formatter, LowerHex, Octal};
10use std::hash::{Hash, Hasher};
11use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub};
12use std::rc::Rc;
13
14#[derive(Debug)]
30pub enum Exactness {
31 Exact,
32 Inexact,
33 Unspecified,
34}
35
36#[derive(Clone, Debug)]
51pub enum Number {
52 Fixnum(i64),
53 Float(f64),
54 BigInt(Rc<BigInt>),
55 Rational(Rational32),
56}
57
58impl Number {
59 pub fn new_bigint<T: Into<BigInt>>(num: T) -> Number {
60 Number::BigInt(Rc::new(num.into()))
61 }
62
63 pub fn parse_with_exactness(text: &str, exactness: Exactness, radix: u32) -> Option<Number> {
67 match exactness {
68 Exactness::Unspecified => Self::parse(text, radix),
69 Exactness::Exact => Self::parse(text, radix).map(|num| match num.to_exact() {
70 Some(num) => num,
71 None => num,
72 }),
73 Exactness::Inexact => Self::parse(text, radix)
74 .map(|num| num.to_inexact())
75 .map(|it| it.unwrap()),
76 }
77 }
78
79 pub fn parse(text: &str, radix: u32) -> Option<Number> {
80 if let Ok(num) = i64::from_str_radix(text, radix) {
81 Some(Number::from(num))
82 } else if let Ok(num) = BigInt::from_str_radix(text, radix) {
83 Some(Number::from(num))
84 } else if let Some(num) = Self::parse_rational(text, radix) {
85 Some(num)
86 } else if let Ok(num) = f64::from_str_radix(text, radix) {
87 Some(Number::from(num))
88 } else {
89 None
90 }
91 }
92
93 pub fn parse_rational(text: &str, radix: u32) -> Option<Number> {
100 match Rational32::from_str_radix(text, radix) {
101 Ok(num) => {
102 if num.is_integer() {
103 Some(Number::from(num.to_i64().unwrap()))
104 } else {
105 Some(num.into())
106 }
107 }
108 Err(_) => match BigRational::from_str_radix(text, radix) {
109 Ok(num) => {
110 if num.is_integer() {
111 match num.to_i64() {
112 Some(num) => Some(num.into()),
113 None => Some(num.to_integer().into()),
114 }
115 } else {
116 Some(num.to_f64().unwrap_or(f64::NAN).into())
117 }
118 }
119 Err(_) => None,
120 },
121 }
122 }
123
124 pub fn to_usize(&self) -> Option<usize> {
125 match self {
126 Number::Fixnum(num) if *num >= 0 => num.to_usize(),
127 Number::BigInt(num)
128 if **num >= BigInt::from(0) && **num <= BigInt::from(usize::MAX) =>
129 {
130 Some(num.to_usize().unwrap())
131 }
132 Number::Rational(num) if num.is_integer() => num.to_usize(),
133 _ => None,
134 }
135 }
136
137 pub fn to_i64(&self) -> Option<i64> {
138 match self {
139 Number::Fixnum(num) => Some(*num),
140 Number::BigInt(num) => num.to_i64(),
141 Number::Rational(num) if num.is_integer() => num.to_i64(),
142 Number::Float(num) if self.is_integer() => num.to_i64(),
143 _ => None,
144 }
145 }
146
147 pub fn to_u64(&self) -> Option<u64> {
148 match self {
149 Number::Fixnum(num) if *num >= 0 => Some(*num as u64),
150 Number::BigInt(num) if **num >= BigInt::from(0) && **num <= BigInt::from(u64::MAX) => {
151 Some(num.to_u64().unwrap())
152 }
153 Number::Rational(num) if num.is_integer() => num.to_u64(),
154 Number::Float(num) if self.is_integer() => num.to_u64(),
155 _ => None,
156 }
157 }
158
159 pub fn to_u32(&self) -> Option<u32> {
160 match self {
161 Number::Fixnum(num) => num.to_u32(),
162 Number::BigInt(num) if **num >= BigInt::from(0) && **num <= BigInt::from(u32::MAX) => {
163 Some(num.to_u32().unwrap())
164 }
165 Number::Rational(num) if num.is_integer() => num.to_u32(),
166 Number::Float(num) if self.is_integer() => num.to_u32(),
167 _ => None,
168 }
169 }
170
171 pub fn to_f64(&self) -> Option<f64> {
172 match self {
173 Number::Fixnum(num) => num.to_f64(),
174 Number::BigInt(num) => num.to_f64(),
175 Number::Rational(num) => num.to_f64(),
176 Number::Float(num) => Some(*num),
177 }
178 }
179
180 pub fn is_integer(&self) -> bool {
181 match self {
182 Number::Fixnum(_) => true,
183 Number::Float(num) => num.floor() == *num,
184 Number::BigInt(_) => true,
185 Number::Rational(num) => num.is_integer(),
186 }
187 }
188
189 pub fn is_complex(&self) -> bool {
190 true
191 }
192
193 pub fn is_real(&self) -> bool {
194 true
195 }
196
197 pub fn is_rational(&self) -> bool {
198 match self {
199 Number::Fixnum(_) => true,
200 Number::Float(_) => false,
201 Number::BigInt(_) => true,
202 Number::Rational(_) => true,
203 }
204 }
205
206 pub fn is_zero(&self) -> bool {
207 self == &Number::from(0)
208 }
209
210 pub fn to_inexact(&self) -> Option<Number> {
211 match self {
212 Number::Fixnum(num) => Some((*num as f64).into()),
213 Number::Float(num) => Some((*num).into()),
214 Number::BigInt(num) => Some(num.to_f64().unwrap().into()),
215 Number::Rational(num) => Some(num.to_f64().unwrap().into()),
216 }
217 }
218
219 pub fn to_exact(&self) -> Option<Number> {
220 match self {
221 Number::Float(num) => {
222 if self.is_integer() {
223 match num.to_i64() {
224 Some(integer) => Some(Number::Fixnum(integer)),
225 None => num.to_i128().map(|num| BigInt::from(num).into()),
226 }
227 } else {
228 match Rational32::from_f64(*num) {
229 Some(num) => Some(num.into()),
230 None => Some((*num).into()),
231 }
232 }
233 }
234 Number::BigInt(_) | Number::Rational(_) | Number::Fixnum(_) => Some(self.clone()),
235 }
236 }
237
238 pub fn numerator(&self) -> Number {
239 match self {
240 Number::Fixnum(_) => self.clone(),
241 Number::Float(num) => match BigRational::from_f64(*num) {
242 Some(rational) => Number::from(rational.numer().clone()),
243 None => self.clone(),
244 },
245 Number::BigInt(_) => self.clone(),
246 Number::Rational(num) => (*num.numer() as i64).into(),
247 }
248 }
249
250 pub fn denominator(&self) -> Number {
251 match self {
252 Number::Fixnum(_) => 1.into(),
253 Number::Float(num) => match BigRational::from_f64(*num) {
254 Some(rational) => Number::from(rational.denom().clone()),
255 None => self.clone(),
256 },
257 Number::BigInt(_) => 1.into(),
258 Number::Rational(num) => (*num.denom() as i64).into(),
259 }
260 }
261
262 pub fn abs(&self) -> Number {
263 match self {
264 Number::Fixnum(num) => num.unsigned_abs().into(),
265 Number::Float(num) => num.abs().into(),
266 Number::BigInt(num) => num.abs().into(),
267 Number::Rational(num) => num.abs().into(),
268 }
269 }
270
271 pub fn modulo(&self, rhs: &Number) -> Option<Number> {
272 match self % rhs {
273 Some(num) => &(&num + rhs) % rhs,
274 None => None,
275 }
276 }
277
278 pub fn round(&self) -> Number {
279 match self {
280 Number::Fixnum(_) => self.clone(),
281 Number::Float(num) => num.round().into(),
282 Number::BigInt(_) => self.clone(),
283 Number::Rational(num) => num.round().into(),
284 }
285 }
286
287 pub fn floor(&self) -> Number {
288 match self {
289 Number::Fixnum(_) => self.clone(),
290 Number::Float(num) => num.floor().into(),
291 Number::BigInt(_) => self.clone(),
292 Number::Rational(num) => num.floor().into(),
293 }
294 }
295
296 pub fn ceil(&self) -> Number {
297 match self {
298 Number::Fixnum(_) => self.clone(),
299 Number::Float(num) => num.ceil().into(),
300 Number::BigInt(_) => self.clone(),
301 Number::Rational(num) => num.ceil().into(),
302 }
303 }
304
305 pub fn truncate(&self) -> Number {
306 match self {
307 Number::Fixnum(_) => self.clone(),
308 Number::Float(num) => num.trunc().into(),
309 Number::BigInt(_) => self.clone(),
310 Number::Rational(num) => num.trunc().into(),
311 }
312 }
313
314 pub fn pow(&self, exp: u32) -> Number {
315 match self {
316 Number::Fixnum(num) => match num.checked_pow(exp) {
317 Some(num) => num.into(),
318 None => BigInt::from(*num).pow(exp).into(),
319 },
320 Number::Float(num) => num.powf(exp as f64).into(),
321 Number::BigInt(lhs) => lhs.pow(exp).into(),
322 Number::Rational(num) => {
323 if exp.to_i32().is_some() {
324 num.pow(exp as i32).into()
325 } else {
326 num.to_f64().unwrap_or(f64::NAN).powf(exp as f64).into()
327 }
328 }
329 }
330 }
331}
332
333impl Eq for Number {}
334impl PartialEq for Number {
335 fn eq(&self, rhs: &Self) -> bool {
336 match self {
337 Number::Fixnum(lhs) => match rhs {
338 Number::Fixnum(rhs) => lhs == rhs,
339 Number::BigInt(rhs) => BigInt::from(*lhs) == **rhs,
340 Number::Float(rhs) => *lhs as f64 == *rhs,
341 Number::Rational(rhs) => {
342 if lhs.to_i32().is_some() {
343 Rational32::from_integer(*lhs as i32) == *rhs
344 } else {
345 false
346 }
347 }
348 },
349 Number::BigInt(lhs) => match rhs {
350 Number::Fixnum(rhs) => **lhs == BigInt::from(*rhs),
351 Number::BigInt(rhs) => lhs == rhs,
352 Number::Float(rhs) => lhs.to_f64().unwrap() == *rhs,
353 Number::Rational(rhs) => match lhs.to_i32() {
354 Some(lhs) => Rational32::from_integer(lhs) == *rhs,
355 None => false,
356 },
357 },
358 Number::Float(lhs) => match rhs {
359 Number::Fixnum(rhs) => *lhs == *rhs as f64,
360 Number::Float(rhs) => lhs == rhs,
361 Number::BigInt(rhs) => *lhs == rhs.to_f64().unwrap(),
362 Number::Rational(rhs) => match rhs.to_f64() {
363 Some(rhs) => *lhs == rhs,
364 None => false,
365 },
366 },
367 Number::Rational(lhs) => match rhs {
368 Number::Fixnum(rhs) => {
369 if rhs.to_i32().is_some() {
370 Rational32::from_integer(*rhs as i32) == *lhs
371 } else {
372 false
373 }
374 }
375 Number::Float(rhs) => match lhs.to_f64() {
376 Some(lhs) => lhs == *rhs,
377 None => false,
378 },
379 Number::BigInt(rhs) => match rhs.to_i32() {
380 Some(rhs) => *lhs == Rational32::from_integer(rhs),
381 None => false,
382 },
383 Number::Rational(rhs) => lhs == rhs,
384 },
385 }
386 }
387}
388
389impl PartialOrd for Number {
390 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
391 match self {
392 Number::Fixnum(lhs) => match rhs {
393 Number::Fixnum(rhs) => lhs.partial_cmp(rhs),
394 Number::BigInt(rhs) => BigInt::from(*lhs).partial_cmp(&**rhs),
395 Number::Float(rhs) => (*lhs as f64).partial_cmp(rhs),
396 Number::Rational(rhs) => {
397 if lhs.to_i32().is_some() {
398 Rational32::from_integer(*lhs as i32).partial_cmp(rhs)
399 } else {
400 Some(Ordering::Greater)
401 }
402 }
403 },
404 Number::BigInt(lhs) => match rhs {
405 Number::Fixnum(rhs) => (**lhs).partial_cmp(&BigInt::from(*rhs)),
406 Number::BigInt(rhs) => (**lhs).partial_cmp(&**rhs),
407 Number::Float(rhs) => (**lhs).to_f64().unwrap().partial_cmp(rhs),
408 Number::Rational(rhs) => match lhs.to_i32() {
409 Some(lhs) => Rational32::from_integer(lhs).partial_cmp(rhs),
410 None => Some(Ordering::Greater),
411 },
412 },
413 Number::Float(lhs) => match rhs {
414 Number::Fixnum(rhs) => lhs.partial_cmp(&(*rhs as f64)),
415 Number::Float(rhs) => lhs.partial_cmp(rhs),
416 Number::BigInt(rhs) => lhs.partial_cmp(&(**rhs).to_f64().unwrap()),
417 Number::Rational(rhs) => lhs.partial_cmp(&rhs.to_f64().unwrap()),
418 },
419 Number::Rational(lhs) => match rhs {
420 Number::Fixnum(rhs) => {
421 if rhs.to_i32().is_some() {
422 lhs.partial_cmp(&Rational32::from_integer(*rhs as i32))
423 } else {
424 Some(Ordering::Less)
425 }
426 }
427 Number::Float(rhs) => lhs.to_f64().unwrap().partial_cmp(rhs),
428 Number::BigInt(rhs) => match rhs.to_i32() {
429 Some(rhs) => lhs.partial_cmp(&Rational32::from_integer(rhs)),
430 None => Some(Ordering::Less),
431 },
432 Number::Rational(rhs) => lhs.partial_cmp(rhs),
433 },
434 }
435 }
436}
437
438impl AddAssign for Number {
439 fn add_assign(&mut self, rhs: Self) {
440 let result = &*self + &rhs;
441 *self = result;
442 }
443}
444
445impl MulAssign for Number {
446 fn mul_assign(&mut self, rhs: Self) {
447 let result = &*self * &rhs;
448 *self = result;
449 }
450}
451
452impl DivAssign for Number {
453 fn div_assign(&mut self, rhs: Self) {
454 let result = &*self / &rhs;
455 *self = result;
456 }
457}
458
459impl Add for Number {
460 type Output = Number;
461 fn add(self, rhs: Self) -> Self::Output {
462 (&self).add(&rhs)
463 }
464}
465
466impl Add for &Number {
467 type Output = Number;
468
469 fn add(self, rhs: Self) -> Self::Output {
470 match self {
471 Number::Fixnum(lhs) => match rhs {
472 Number::Fixnum(rhs) => match lhs.checked_add(rhs) {
473 Some(num) => Number::Fixnum(num),
474 None => (BigInt::from(*lhs) + rhs).into(),
475 },
476 Number::BigInt(rhs) => (&**rhs + lhs).into(),
477 Number::Float(rhs) => (*lhs as f64 + rhs).into(),
478 Number::Rational(rhs) => {
479 if lhs.to_i32().is_some() {
480 let lhs_rational = Rational32::from_integer(*lhs as i32);
481 match lhs_rational.checked_add(rhs) {
482 Some(num) => num.into(),
483 None => (*lhs as f64 + rhs.to_f64().unwrap_or(f64::NAN)).into(),
484 }
485 } else {
486 (*lhs as f64 + rhs.to_f64().unwrap_or(f64::NAN)).into()
487 }
488 }
489 },
490 Number::BigInt(lhs) => match rhs {
491 Number::Fixnum(rhs) => (&**lhs + rhs).into(),
492 Number::BigInt(rhs) => (&**lhs + &**rhs).into(),
493 Number::Float(rhs) => (lhs.to_f64().unwrap() + *rhs).into(),
494 Number::Rational(rhs) => {
495 if rhs.is_integer() {
496 (&**lhs + rhs.to_integer()).into()
497 } else {
498 (lhs.to_f64().unwrap() + rhs.to_f64().unwrap_or(f64::NAN)).into()
499 }
500 }
501 },
502 Number::Float(lhs) => match rhs {
503 Number::Fixnum(rhs) => (*lhs + *rhs as f64).into(),
504 Number::Float(rhs) => (*lhs + *rhs).into(),
505 Number::BigInt(rhs) => (*lhs + rhs.to_f64().unwrap()).into(),
506 Number::Rational(rhs) => (*lhs + rhs.to_f64().unwrap_or(f64::NAN)).into(),
507 },
508 Number::Rational(lhs) => match rhs {
509 Number::Fixnum(rhs) => {
510 if rhs.to_i32().is_some() {
511 let rhs_rational = Rational32::from_integer(*rhs as i32);
512 match rhs_rational.checked_add(lhs) {
513 Some(num) => num.into(),
514 None => (lhs.to_f64().unwrap_or(f64::NAN) + *rhs as f64).into(),
515 }
516 } else {
517 (lhs.to_f64().unwrap_or(f64::NAN) + *rhs as f64).into()
518 }
519 }
520 Number::Float(rhs) => (lhs.to_f64().unwrap_or(f64::NAN) + *rhs).into(),
521 Number::BigInt(rhs) => {
522 if lhs.is_integer() {
523 (&**rhs + lhs.to_integer()).into()
524 } else {
525 (rhs.to_f64().unwrap() + lhs.to_f64().unwrap_or(f64::NAN)).into()
526 }
527 }
528 Number::Rational(rhs) => match lhs.checked_add(rhs) {
529 Some(num) => num.into(),
530 None => {
531 (lhs.to_f64().unwrap_or(f64::NAN) + rhs.to_f64().unwrap_or(f64::NAN)).into()
532 }
533 },
534 },
535 }
536 }
537}
538
539impl Mul for Number {
540 type Output = Number;
541 fn mul(self, rhs: Self) -> Self::Output {
542 (&self).mul(&rhs)
543 }
544}
545
546impl Mul for &Number {
547 type Output = Number;
548
549 fn mul(self, rhs: Self) -> Self::Output {
550 match self {
551 Number::Fixnum(lhs) => match rhs {
552 Number::Fixnum(rhs) => match lhs.checked_mul(rhs) {
553 Some(num) => Number::Fixnum(num),
554 None => (BigInt::from(*lhs) * rhs).into(),
555 },
556 Number::BigInt(rhs) => (&**rhs * lhs).into(),
557 Number::Float(rhs) => (*lhs as f64 * rhs).into(),
558 Number::Rational(rhs) => {
559 if lhs.to_i32().is_some() {
560 let lhs_rational = Rational32::from_integer(*lhs as i32);
561 match lhs_rational.checked_mul(rhs) {
562 Some(num) => num.into(),
563 None => (*lhs as f64 * rhs.to_f64().unwrap_or(f64::NAN)).into(),
564 }
565 } else {
566 (*lhs as f64 * rhs.to_f64().unwrap_or(f64::NAN)).into()
567 }
568 }
569 },
570 Number::BigInt(lhs) => match rhs {
571 Number::Fixnum(rhs) => (&**lhs * rhs).into(),
572 Number::BigInt(rhs) => (&**lhs * &**rhs).into(),
573 Number::Float(rhs) => (lhs.to_f64().unwrap() * *rhs).into(),
574 Number::Rational(rhs) => {
575 if rhs.is_integer() {
576 (&**lhs * rhs.to_integer()).into()
577 } else {
578 (lhs.to_f64().unwrap() * rhs.to_f64().unwrap_or(f64::NAN)).into()
579 }
580 }
581 },
582 Number::Float(lhs) => match rhs {
583 Number::Fixnum(rhs) => (*lhs * *rhs as f64).into(),
584 Number::Float(rhs) => (*lhs * *rhs).into(),
585 Number::BigInt(rhs) => (*lhs * rhs.to_f64().unwrap()).into(),
586 Number::Rational(rhs) => (*lhs * rhs.to_f64().unwrap_or(f64::NAN)).into(),
587 },
588 Number::Rational(lhs) => match rhs {
589 Number::Fixnum(rhs) => {
590 if rhs.to_i32().is_some() {
591 let rhs_rational = Rational32::from_integer(*rhs as i32);
592 match rhs_rational.checked_mul(lhs) {
593 Some(num) => num.into(),
594 None => (lhs.to_f64().unwrap_or(f64::NAN) * *rhs as f64).into(),
595 }
596 } else {
597 (lhs.to_f64().unwrap_or(f64::NAN) * *rhs as f64).into()
598 }
599 }
600 Number::Float(rhs) => (lhs.to_f64().unwrap_or(f64::NAN) * *rhs).into(),
601 Number::BigInt(rhs) => {
602 if lhs.is_integer() {
603 (&**rhs * lhs.to_integer()).into()
604 } else {
605 (rhs.to_f64().unwrap() * lhs.to_f64().unwrap_or(f64::NAN)).into()
606 }
607 }
608 Number::Rational(rhs) => match lhs.checked_mul(rhs) {
609 Some(num) => num.into(),
610 None => {
611 (lhs.to_f64().unwrap_or(f64::NAN) * rhs.to_f64().unwrap_or(f64::NAN)).into()
612 }
613 },
614 },
615 }
616 }
617}
618
619impl Sub for Number {
620 type Output = Number;
621 fn sub(self, rhs: Self) -> Self::Output {
622 (&self).sub(&rhs)
623 }
624}
625
626impl Sub for &Number {
627 type Output = Number;
628
629 fn sub(self, rhs: Self) -> Self::Output {
630 match self {
631 Number::Fixnum(lhs) => match rhs {
632 Number::Fixnum(rhs) => match lhs.checked_sub(rhs) {
633 Some(num) => Number::Fixnum(num),
634 None => (BigInt::from(*lhs) - rhs).into(),
635 },
636 Number::BigInt(rhs) => (lhs - &**rhs).into(),
637 Number::Float(rhs) => (*lhs as f64 - rhs).into(),
638 Number::Rational(rhs) => {
639 if lhs.to_i32().is_some() {
640 let lhs_rational = Rational32::from_integer(*lhs as i32);
641 match lhs_rational.checked_sub(rhs) {
642 Some(num) => num.into(),
643 None => (*lhs as f64 - rhs.to_f64().unwrap_or(f64::NAN)).into(),
644 }
645 } else {
646 (*lhs as f64 - rhs.to_f64().unwrap_or(f64::NAN)).into()
647 }
648 }
649 },
650 Number::BigInt(lhs) => match rhs {
651 Number::Fixnum(rhs) => (&**lhs - rhs).into(),
652 Number::BigInt(rhs) => (&**lhs - &**rhs).into(),
653 Number::Float(rhs) => (lhs.to_f64().unwrap() - *rhs).into(),
654 Number::Rational(rhs) => {
655 if rhs.is_integer() {
656 (&**lhs - rhs.to_integer()).into()
657 } else {
658 (lhs.to_f64().unwrap() - rhs.to_f64().unwrap_or(f64::NAN)).into()
659 }
660 }
661 },
662 Number::Float(lhs) => match rhs {
663 Number::Fixnum(rhs) => (*lhs - *rhs as f64).into(),
664 Number::Float(rhs) => (*lhs - *rhs).into(),
665 Number::BigInt(rhs) => (*lhs - rhs.to_f64().unwrap()).into(),
666 Number::Rational(rhs) => (*lhs - rhs.to_f64().unwrap_or(f64::NAN)).into(),
667 },
668 Number::Rational(lhs) => match rhs {
669 Number::Fixnum(rhs) => {
670 if rhs.to_i32().is_some() {
671 let rhs_rational = Rational32::from_integer(*rhs as i32);
672 match lhs.checked_sub(&rhs_rational) {
673 Some(num) => num.into(),
674 None => (lhs.to_f64().unwrap_or(f64::NAN) - *rhs as f64).into(),
675 }
676 } else {
677 (lhs.to_f64().unwrap_or(f64::NAN) - *rhs as f64).into()
678 }
679 }
680 Number::Float(rhs) => (lhs.to_f64().unwrap_or(f64::NAN) - *rhs).into(),
681 Number::BigInt(rhs) => {
682 if lhs.is_integer() {
683 (BigInt::from(lhs.to_integer()) - &**rhs).into()
684 } else {
685 (lhs.to_f64().unwrap_or(f64::NAN) - rhs.to_f64().unwrap()).into()
686 }
687 }
688 Number::Rational(rhs) => match lhs.checked_sub(rhs) {
689 Some(num) => num.into(),
690 None => {
691 (lhs.to_f64().unwrap_or(f64::NAN) - rhs.to_f64().unwrap_or(f64::NAN)).into()
692 }
693 },
694 },
695 }
696 }
697}
698
699impl Div for Number {
700 type Output = Number;
701 fn div(self, rhs: Self) -> Self::Output {
702 (&self).div(&rhs)
703 }
704}
705
706impl Div for &Number {
707 type Output = Number;
708
709 fn div(self, rhs: Self) -> Self::Output {
710 match self {
711 Number::Fixnum(lhs) => match rhs {
712 Number::Fixnum(rhs) => {
713 if lhs.to_i32().is_some() && rhs.to_i32().is_some() {
714 Rational32::new(*lhs as i32, *rhs as i32).into()
715 } else {
716 (*lhs as f64 / *rhs as f64).into()
717 }
718 }
719 Number::BigInt(rhs) => {
720 if lhs.to_i32().is_some() && rhs.to_i32().is_some() {
721 Rational32::new(*lhs as i32, rhs.to_i32().unwrap()).into()
722 } else {
723 (*lhs as f64 / rhs.to_f64().unwrap_or(f64::NAN)).into()
724 }
725 }
726 Number::Float(rhs) => (*lhs as f64 / rhs).into(),
727 Number::Rational(rhs) => {
728 if lhs.to_i32().is_some() {
729 match Rational32::from_integer(*lhs as i32).checked_div(rhs) {
730 Some(num) => num.into(),
731 None => (*lhs as f64 / rhs.to_f64().unwrap_or(f64::NAN)).into(),
732 }
733 } else {
734 (*lhs as f64 / rhs.to_f64().unwrap_or(f64::NAN)).into()
735 }
736 }
737 },
738 Number::BigInt(lhs) => match rhs {
739 Number::Fixnum(rhs) => {
740 if lhs.to_i32().is_some() && rhs.to_i32().is_some() {
741 (Rational32::new(lhs.to_i32().unwrap(), *rhs as i32)).into()
742 } else {
743 (lhs.to_f64().unwrap_or(f64::NAN) / *rhs as f64).into()
744 }
745 }
746 Number::BigInt(rhs) => {
747 if lhs.to_i32().is_some() && rhs.to_i32().is_some() {
748 (Rational32::new(lhs.to_i32().unwrap(), rhs.to_i32().unwrap())).into()
749 } else {
750 (lhs.to_f64().unwrap_or(f64::NAN) / rhs.to_f64().unwrap_or(f64::NAN)).into()
751 }
752 }
753 Number::Float(rhs) => (lhs.to_f64().unwrap() / *rhs).into(),
754 Number::Rational(rhs) => {
755 if lhs.to_i32().is_some() {
756 match Rational32::from_integer(lhs.to_i32().unwrap()).checked_div(rhs) {
757 Some(num) => num.into(),
758 None => {
759 (lhs.to_f64().unwrap() / rhs.to_f64().unwrap_or(f64::NAN)).into()
760 }
761 }
762 } else {
763 (lhs.to_f64().unwrap() / rhs.to_f64().unwrap_or(f64::NAN)).into()
764 }
765 }
766 },
767 Number::Float(lhs) => match rhs {
768 Number::Fixnum(rhs) => (*lhs / *rhs as f64).into(),
769 Number::Float(rhs) => (*lhs / *rhs).into(),
770 Number::BigInt(rhs) => (*lhs / rhs.to_f64().unwrap()).into(),
771 Number::Rational(rhs) => (lhs / rhs.to_f64().unwrap_or(f64::NAN)).into(),
772 },
773 Number::Rational(lhs) => match rhs {
774 Number::Fixnum(rhs) => {
775 if rhs.to_i32().is_some() {
776 match lhs.checked_div(&Rational32::from_integer(*rhs as i32)) {
777 Some(num) => num.into(),
778 None => (lhs.to_f64().unwrap_or(f64::MAX) / *rhs as f64).into(),
779 }
780 } else {
781 (lhs.to_f64().unwrap_or(f64::MAX) / *rhs as f64).into()
782 }
783 }
784 Number::Float(rhs) => (lhs.to_f64().unwrap_or(f64::NAN) / *rhs).into(),
785 Number::BigInt(rhs) => {
786 if rhs.to_i32().is_some() {
787 match lhs.checked_div(&Rational32::from_integer(rhs.to_i32().unwrap())) {
788 Some(num) => num.into(),
789 None => {
790 (lhs.to_f64().unwrap_or(f64::MAX) / rhs.to_f64().unwrap()).into()
791 }
792 }
793 } else {
794 (lhs.to_f64().unwrap_or(f64::MAX) / rhs.to_f64().unwrap()).into()
795 }
796 }
797 Number::Rational(rhs) => match lhs.checked_div(rhs) {
798 Some(num) => num.into(),
799 None => {
800 (lhs.to_f64().unwrap_or(f64::NAN) / rhs.to_f64().unwrap_or(f64::NAN)).into()
801 }
802 },
803 },
804 }
805 }
806}
807
808impl Number {
809 pub fn quotient(&self, rhs: &Self) -> Option<Number> {
815 match self {
816 Number::Fixnum(lhs) => match rhs {
817 Number::Fixnum(rhs) => Some((lhs / rhs).into()),
818 Number::BigInt(rhs) => Some((BigInt::from(*lhs) / &**rhs).into()),
819 Number::Float(rhs) => lhs.to_f64().map(|lhs| (lhs as f64 / rhs).trunc().into()),
820 Number::Rational(rhs) => {
821 if rhs.is_integer() {
822 Some((*lhs / rhs.to_i64().unwrap()).into())
823 } else {
824 None
825 }
826 }
827 },
828 Number::BigInt(lhs) => match rhs {
829 Number::Fixnum(rhs) => Some((&**lhs / rhs).into()),
830 Number::BigInt(rhs) => Some((&**lhs / &**rhs).into()),
831 Number::Float(rhs) => lhs.to_f64().map(|lhs| (lhs / rhs).trunc().into()),
832 Number::Rational(rhs) => {
833 if rhs.is_integer() {
834 Some((&**lhs / BigInt::from(rhs.to_i32().unwrap())).into())
835 } else {
836 None
837 }
838 }
839 },
840 Number::Float(lhs) => match rhs {
841 Number::Fixnum(rhs) => Some((lhs / *rhs as f64).into()),
842 Number::Float(rhs) => Some((lhs / rhs).trunc().into()),
843 Number::BigInt(_) => None,
844 Number::Rational(rhs) => rhs.to_f64().map(|rhs| (lhs / rhs).into()),
845 },
846 Number::Rational(lhs) if lhs.is_integer() => match rhs {
847 Number::Fixnum(rhs) => Some((lhs.to_i64().unwrap() / *rhs).into()),
848 Number::Float(rhs) => lhs.to_f64().map(|lhs| (lhs / rhs).trunc().into()),
849 Number::BigInt(rhs) => Some((BigInt::from(lhs.to_i64().unwrap()) / &**rhs).into()),
850 Number::Rational(rhs) => {
851 if rhs.is_integer() {
852 Some((lhs / rhs).into())
853 } else {
854 None
855 }
856 }
857 },
858 Number::Rational(_) => None,
859 }
860 }
861}
862
863impl Rem for Number {
864 type Output = Option<Number>;
865 fn rem(self, rhs: Self) -> Self::Output {
866 (&self).rem(&rhs)
867 }
868}
869
870impl Rem for &Number {
871 type Output = Option<Number>;
872
873 fn rem(self, rhs: Self) -> Self::Output {
878 match self {
879 Number::Fixnum(lhs) => match rhs {
880 Number::Fixnum(rhs) => Some((lhs % rhs).into()),
881 Number::BigInt(rhs) => Some((BigInt::from(*lhs) % &**rhs).into()),
882 Number::Float(rhs) => Some((*lhs as f64 % rhs).into()),
883 Number::Rational(rhs) => {
884 let result = Rational64::from_integer(*lhs)
885 % Rational64::from((*rhs.numer() as i64, *rhs.denom() as i64));
886 Some(Rational32::from((*result.numer() as i32, *result.denom() as i32)).into())
889 }
890 },
891 Number::BigInt(lhs) => match rhs {
892 Number::Fixnum(rhs) => Some((&**lhs % rhs).into()),
893 Number::BigInt(rhs) => Some((&**lhs % &**rhs).into()),
894 Number::Float(_) => None,
895 Number::Rational(rhs) => {
896 if rhs.is_integer() {
897 Some((&**lhs % BigInt::from(rhs.to_i32().unwrap())).into())
899 } else {
900 let denom = rhs.denom();
904 let numer_mod =
905 (&**lhs * BigInt::from(*denom)) % BigInt::from(*rhs.numer());
906 Some(Rational32::new(numer_mod.to_i32().unwrap(), *denom).into())
907 }
908 }
909 },
910 Number::Float(lhs) => match rhs {
911 Number::Fixnum(rhs) => Some((lhs % *rhs as f64).into()),
912 Number::Float(rhs) => Some((lhs % rhs).into()),
913 Number::BigInt(rhs) => rhs.to_f64().map(|rhs| (lhs % rhs).into()),
916 Number::Rational(rhs) => rhs.to_f64().map(|rhs| (lhs % rhs).into()),
917 },
918 Number::Rational(lhs) => match rhs {
919 Number::Fixnum(rhs) => Some((lhs.to_i64().unwrap() % *rhs).into()),
920 Number::Float(rhs) => lhs.to_f64().map(|lhs| (lhs % rhs).into()),
921 Number::BigInt(rhs) => Some((BigInt::from(lhs.to_i64().unwrap()) % &**rhs).into()),
922 Number::Rational(rhs) => Some((lhs % rhs).into()),
923 },
924 }
925 }
926}
927
928impl Hash for Number {
929 fn hash<H: Hasher>(&self, state: &mut H) {
930 match self {
931 Number::Fixnum(num) => num.hash(state),
932 Number::Float(_) => panic!("unexpected hash of f64"),
933 Number::BigInt(num) => num.hash(state),
934 Number::Rational(num) => num.hash(state),
935 }
936 }
937}
938
939impl fmt::Display for Number {
940 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
941 match self {
942 Number::Fixnum(num) => write!(f, "{}", num),
943 Number::BigInt(num) => write!(f, "{}", num),
944 Number::Float(num) if *num > 1E10 => write!(f, "{:e}", num),
945 Number::Float(num) if self.is_integer() => write!(f, "{:.1}", num),
946 Number::Float(num) => write!(f, "{}", num),
947 Number::Rational(num) => write!(f, "{}", num),
948 }
949 }
950}
951
952fn write_float_fract(mut num: f64, radix: usize, f: &mut Formatter<'_>) -> fmt::Result {
953 let mut first_digit = true;
954 loop {
955 num = num.fract() * radix as f64;
956 if num == 0_f64 {
957 break;
958 }
959 if first_digit {
960 write!(f, ".{:x}", num.trunc().abs() as i64)?;
961 first_digit = false;
962 } else {
963 write!(f, "{:x}", num.trunc().abs() as i64)?;
964 }
965 }
966 Ok(())
967}
968
969impl LowerHex for Number {
970 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
971 match self {
972 Number::Fixnum(num) => fmt::LowerHex::fmt(num, f),
973 Number::Float(num) => {
974 if *num < 0_f64 {
975 write!(f, "-")?;
976 }
977 write!(f, "{:x}", num.trunc().abs() as i64)?;
978 write_float_fract(*num, 16, f)
979 }
980 Number::BigInt(num) => fmt::LowerHex::fmt(num.as_ref(), f),
981 Number::Rational(num) => fmt::LowerHex::fmt(num, f),
982 }
983 }
984}
985
986impl Octal for Number {
987 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
988 match self {
989 Number::Fixnum(num) => fmt::Octal::fmt(num, f),
990 Number::Float(num) => {
991 if *num < 0_f64 {
992 write!(f, "-")?;
993 }
994 write!(f, "{:o}", num.trunc().abs() as i64)?;
995 write_float_fract(*num, 8, f)
996 }
997 Number::BigInt(num) => fmt::Octal::fmt(num.as_ref(), f),
998 Number::Rational(num) => fmt::Octal::fmt(num, f),
999 }
1000 }
1001}
1002
1003impl Binary for Number {
1004 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1005 match self {
1006 Number::Fixnum(num) => fmt::Binary::fmt(num, f),
1007 Number::Float(num) => {
1008 if *num < 0_f64 {
1009 write!(f, "-")?;
1010 }
1011 write!(f, "{:b}", num.trunc().abs() as i64)?;
1012 write_float_fract(*num, 2, f)
1013 }
1014 Number::BigInt(num) => fmt::Binary::fmt(num.as_ref(), f),
1015 Number::Rational(num) => fmt::Binary::fmt(num, f),
1016 }
1017 }
1018}
1019
1020impl From<u32> for Number {
1021 fn from(num: u32) -> Self {
1022 Number::Fixnum(num as i64)
1023 }
1024}
1025
1026impl From<i32> for Number {
1027 fn from(num: i32) -> Self {
1028 Number::Fixnum(num as i64)
1029 }
1030}
1031
1032impl From<u64> for Number {
1033 fn from(num: u64) -> Self {
1034 if num > i64::MAX as u64 {
1035 Number::new_bigint(BigInt::from(num))
1036 } else {
1037 Number::Fixnum(num as i64)
1038 }
1039 }
1040}
1041
1042impl From<usize> for Number {
1043 fn from(num: usize) -> Self {
1044 if num > i64::MAX as usize {
1045 Number::new_bigint(BigInt::from(num))
1046 } else {
1047 Number::Fixnum(num as i64)
1048 }
1049 }
1050}
1051
1052impl From<i64> for Number {
1053 fn from(num: i64) -> Self {
1054 Number::Fixnum(num)
1055 }
1056}
1057
1058impl From<f64> for Number {
1059 fn from(num: f64) -> Self {
1060 Number::Float(num)
1061 }
1062}
1063
1064impl From<BigInt> for Number {
1065 fn from(num: BigInt) -> Self {
1066 Number::BigInt(Rc::new(num))
1067 }
1068}
1069
1070impl From<Rational32> for Number {
1071 fn from(num: Rational32) -> Self {
1072 Number::Rational(num)
1073 }
1074}
1075
1076impl Number {
1078 pub fn exp(&self) -> Option<Number> {
1079 match self {
1080 Number::Fixnum(num) => num.to_f64().map(|num| num.exp().into()),
1081 Number::Float(num) => Some(num.exp().into()),
1082 Number::BigInt(num) => num.to_f64().map(|num| num.exp().into()),
1083 Number::Rational(num) => num.to_f64().map(|num| num.exp().into()),
1084 }
1085 }
1086
1087 pub fn log(&self) -> Option<Number> {
1088 match self {
1089 Number::Fixnum(num) => num.to_f64().map(|num| num.log(f64::E()).into()),
1090 Number::Float(num) => Some(num.log(f64::E()).into()),
1091 Number::BigInt(num) => num.to_f64().map(|num| num.log(f64::E()).into()),
1092 Number::Rational(num) => num.to_f64().map(|num| num.log(f64::E()).into()),
1093 }
1094 }
1095
1096 pub fn sin(&self) -> Option<Number> {
1097 match self {
1098 Number::Fixnum(num) => num.to_f64().map(|num| num.sin().into()),
1099 Number::Float(num) => Some(num.sin().into()),
1100 Number::BigInt(num) => num.to_f64().map(|num| num.sin().into()),
1101 Number::Rational(num) => num.to_f64().map(|num| num.sin().into()),
1102 }
1103 }
1104
1105 pub fn cos(&self) -> Option<Number> {
1106 match self {
1107 Number::Fixnum(num) => num.to_f64().map(|num| num.cos().into()),
1108 Number::Float(num) => Some(num.cos().into()),
1109 Number::BigInt(num) => num.to_f64().map(|num| num.cos().into()),
1110 Number::Rational(num) => num.to_f64().map(|num| num.cos().into()),
1111 }
1112 }
1113
1114 pub fn tan(&self) -> Option<Number> {
1115 match self {
1116 Number::Fixnum(num) => num.to_f64().map(|num| num.tan().into()),
1117 Number::Float(num) => Some(num.tan().into()),
1118 Number::BigInt(num) => num.to_f64().map(|num| num.tan().into()),
1119 Number::Rational(num) => num.to_f64().map(|num| num.tan().into()),
1120 }
1121 }
1122
1123 pub fn asin(&self) -> Option<Number> {
1124 match self {
1125 Number::Fixnum(num) => num.to_f64().map(|num| num.asin().into()),
1126 Number::Float(num) => Some(num.asin().into()),
1127 Number::BigInt(num) => num.to_f64().map(|num| num.asin().into()),
1128 Number::Rational(num) => num.to_f64().map(|num| num.asin().into()),
1129 }
1130 }
1131
1132 pub fn acos(&self) -> Option<Number> {
1133 match self {
1134 Number::Fixnum(num) => num.to_f64().map(|num| num.acos().into()),
1135 Number::Float(num) => Some(num.acos().into()),
1136 Number::BigInt(num) => num.to_f64().map(|num| num.acos().into()),
1137 Number::Rational(num) => num.to_f64().map(|num| num.acos().into()),
1138 }
1139 }
1140
1141 pub fn atan(&self) -> Option<Number> {
1142 match self {
1143 Number::Fixnum(num) => num.to_f64().map(|num| num.atan().into()),
1144 Number::Float(num) => Some(num.atan().into()),
1145 Number::BigInt(num) => num.to_f64().map(|num| num.atan().into()),
1146 Number::Rational(num) => num.to_f64().map(|num| num.atan().into()),
1147 }
1148 }
1149
1150 pub fn atan2(&self, x: Number) -> Option<Number> {
1151 if let Some(x) = x.to_f64() {
1152 match self {
1153 Number::Fixnum(num) => num.to_f64().map(|num| num.atan2(x).into()),
1154 Number::Float(num) => Some(num.atan2(x).into()),
1155 Number::BigInt(num) => num.to_f64().map(|num| num.atan2(x).into()),
1156 Number::Rational(num) => num.to_f64().map(|num| num.atan2(x).into()),
1157 }
1158 } else {
1159 None
1160 }
1161 }
1162
1163 pub fn sqrt(&self) -> Option<Number> {
1165 let result: Option<Number> = match self {
1166 Number::Fixnum(num) => num.to_f64().map(|num| num.sqrt().into()),
1167 Number::Float(num) => Some(num.sqrt().into()),
1168 Number::BigInt(num) => num.to_f64().map(|num| num.sqrt().into()),
1169 Number::Rational(num) => num.to_f64().map(|num| num.sqrt().into()),
1170 };
1171
1172 if let Some(r) = &result {
1174 if r.to_f64().unwrap().is_finite() {
1175 result
1176 } else {
1177 None
1178 }
1179 } else {
1180 result
1181 }
1182 }
1183}
1184
1185#[cfg(test)]
1186mod tests {
1187 use crate::number::Number;
1188 use num::bigint::BigInt;
1189 use num::traits::FloatConst;
1190 use num::{FromPrimitive, Rational32};
1191 use std::mem;
1192 use std::str::FromStr;
1193
1194 macro_rules! verify {
1195 ($func:expr, $($lhs:expr, $rhs:expr => $result:expr),+) => {{
1196 $(
1197 assert_eq!($func(Number::from($lhs), Number::from($rhs)), Number::from($result),
1198 "{:?} {:?} != {:?}", $lhs, $rhs, $result);
1199 assert_eq!(mem::discriminant(&$func(Number::from($lhs), Number::from($rhs))),
1200 mem::discriminant(&Number::from($result)),
1201 "{:?} {:?} != {:?}", $lhs, $rhs, $result);
1202 )+
1203 }};
1204 }
1205
1206 #[test]
1207 fn to_usize() {
1208 assert!(Number::from(0).to_usize().is_some());
1209 assert!(Number::from(-1).to_usize().is_none());
1210 assert!(Number::from(1.0).to_usize().is_none());
1211 let overflow_num = Number::from(BigInt::from(usize::MAX)) + Number::from(1);
1212 assert!(overflow_num.to_usize().is_none());
1213 assert_eq!(Number::from(Rational32::new(10, 1)).to_usize(), Some(10));
1214 }
1215
1216 #[test]
1217 fn eq() {
1218 assert_eq!(Number::from(100), Number::from(100));
1219 assert_ne!(Number::from(100), Number::from(150));
1220
1221 assert_eq!(Number::from(100.0), Number::from(100));
1222 assert_eq!(Number::from(100), Number::from(100.0));
1223
1224 assert_eq!(
1225 Number::from(100),
1226 Number::from(BigInt::from_str("100").unwrap())
1227 );
1228 assert_eq!(
1229 Number::from(BigInt::from_str("100").unwrap()),
1230 Number::from(100)
1231 );
1232
1233 assert_eq!(
1234 Number::from(100.0),
1235 Number::from(BigInt::from_str("100").unwrap())
1236 );
1237 assert_eq!(
1238 Number::from(BigInt::from_str("100").unwrap()),
1239 Number::from(100.0)
1240 );
1241
1242 assert_eq!(Number::from(Rational32::new(1, 2)), Number::from(0.5));
1243 assert_eq!(Number::from(0.5), Number::from(Rational32::new(1, 2)));
1244
1245 assert_ne!(Number::from(Rational32::new(1, 2)), Number::from(0));
1246 }
1247
1248 #[test]
1249 fn partial_ord() {
1250 assert!(Number::from(200) > Number::from(100));
1251 assert!(!(Number::from(100) > Number::from(100)));
1252 assert!(Number::from(100) >= Number::from(100));
1253 assert!(Number::from(200) >= Number::from(100));
1254
1255 assert!(Number::from(200) > Number::from(100.0));
1256 assert!(Number::from(200.0) > Number::from(100));
1257 assert!(Number::from(200.0) > Number::from(100.0));
1258
1259 assert!(Number::from(200) > Number::new_bigint(100));
1260 assert!(Number::from(200) >= Number::new_bigint(100));
1261 assert!(Number::from(200.0) > Number::new_bigint(100));
1262
1263 assert!(Number::new_bigint(200) > Number::new_bigint(100));
1264 assert!(Number::new_bigint(200) >= Number::new_bigint(100));
1265 assert!(Number::new_bigint(200) > Number::new_bigint(100));
1266
1267 assert!(Number::new_bigint(200) > Number::from(100.0));
1268 assert!(Number::new_bigint(200) >= Number::from(100.0));
1269 assert!(Number::new_bigint(200) > Number::from(100.0));
1270 }
1271
1272 #[test]
1273 fn add() {
1274 let i32_overflow = i32::MAX as i64 + 1;
1275
1276 verify![|x, y| x + y,
1278 100, 50 => 150,
1279 100, i64::MAX => BigInt::from(i64::MAX) + 100,
1280 100, BigInt::from(50) => BigInt::from(150),
1281 100, 50.0 => 150.0,
1282 100, Rational32::from_integer(50) => Rational32::from_integer(150),
1283 i32_overflow, Rational32::from_integer(50) => i32_overflow as f64 + 50_f64
1284 ];
1285
1286 verify![|x, y| x + y,
1288 BigInt::from(100), 50 => BigInt::from(150),
1289 BigInt::from(100), i64::MAX => BigInt::from(i64::MAX) + 100,
1290 BigInt::from(100), 50.0 => 150.0,
1291 BigInt::from(100), Rational32::from_integer(50) => BigInt::from(150),
1292 BigInt::from(100), Rational32::new(1, 2) => 100.50
1293 ];
1294
1295 verify![|x, y| x + y,
1297 100.0, 50 => 150.0,
1298 100.0, 50.0 => 150.0,
1299 100.0, BigInt::from(50) => 150.0,
1300 100.0, Rational32::from_integer(50) => 150.0
1301 ];
1302
1303 verify![|x, y| x + y,
1305 Rational32::from_integer(100), 50 => Rational32::from_integer(150),
1306 Rational32::from_integer(100), i32_overflow => 100.0 + i32_overflow as f64,
1307 Rational32::from_integer(100), 50.0 => 150.0,
1308 Rational32::from_integer(100), BigInt::from(50) => BigInt::from(150),
1309 Rational32::new(1, 2), BigInt::from(50) => 50.50,
1310 Rational32::from_integer(i32::MAX), Rational32::from_integer(1) => i32::MAX as f64 + 1_f64
1311 ];
1312 }
1313
1314 #[test]
1315 fn mul() {
1316 let i32_overflow = i32::MAX as i64 + 1;
1317
1318 verify![|x, y| x * y,
1320 100, 50 => 5000,
1321 100, i64::MAX => BigInt::from(i64::MAX) * 100,
1322 100, BigInt::from(50) => BigInt::from(5000),
1323 100, 50.0 => 5000.0,
1324 100, Rational32::from_integer(50) => Rational32::from_integer(5000),
1325 i32_overflow, Rational32::from_integer(50) => i32_overflow as f64 * 50_f64
1326 ];
1327
1328 verify![|x, y| x * y,
1330 BigInt::from(100), 50 => BigInt::from(5000),
1331 BigInt::from(100), BigInt::from(50) => BigInt::from(5000),
1332 BigInt::from(100), 50.0 => 5000.0,
1333 BigInt::from(100), Rational32::from_integer(50) => BigInt::from(5000),
1334 BigInt::from(100), Rational32::new(1, 2) => 50.0
1335 ];
1336 verify![|x, y| x * y,
1339 100.0, 50 => 5000.0,
1340 100.0, 50.0 => 5000.0,
1341 100.0, BigInt::from(50) => 5000.0,
1342 100.0, Rational32::from_integer(50) => 5000.0
1343 ];
1344 verify![|x, y| x * y,
1347 Rational32::from_integer(100), 50 => Rational32::from_integer(5000),
1348 Rational32::from_integer(100), i32_overflow => 100.0 * i32_overflow as f64,
1349 Rational32::from_integer(100), 50.0 => 5000.0,
1350 Rational32::from_integer(100), BigInt::from(50) => BigInt::from(5000),
1351 Rational32::new(1, 2), BigInt::from(100) => 50.0,
1352 Rational32::from_integer(100), Rational32::from_integer(50) => Rational32::from_integer(5000),
1353 Rational32::from_integer(i32::MAX), Rational32::from_integer(2) => i32::MAX as f64 * 2_f64
1354 ];
1355 }
1356
1357 #[test]
1358 fn sub() {
1359 let i32_overflow = i32::MIN as i64 - 1;
1360
1361 verify![|x, y| x - y,
1363 100, 50 => 50,
1364 -100, i64::MAX => BigInt::from(-i64::MAX) - 100,
1365 100, BigInt::from(50) => BigInt::from(50),
1366 100, 50.0 => 50.0,
1367 100, Rational32::from_integer(50) => Rational32::from_integer(50),
1368 i32::MIN as i64, Rational32::from_integer(50) => i32::MIN as f64 - 50_f64,
1369 i32_overflow, Rational32::from_integer(50) => i32_overflow as f64 - 50_f64
1370 ];
1371
1372 verify![|x, y| x - y,
1374 BigInt::from(100), 50 => BigInt::from(50),
1375 BigInt::from(100), BigInt::from(50) => BigInt::from(50),
1376 BigInt::from(100), 50.0 => 50.0,
1377 BigInt::from(100), Rational32::from_integer(50) => BigInt::from(50),
1378 BigInt::from(100), Rational32::new(1, 2) => 99.50
1379 ];
1380
1381 verify![|x, y| x - y,
1383 100.0, 50 => 50.0,
1384 100.0, 50.0 => 50.0,
1385 100.0, BigInt::from(50) => 50.0,
1386 100.0, Rational32::from_integer(50) => 50.0,
1387 100.0, Rational32::new(1, 2) => 99.50
1388 ];
1389
1390 verify![|x, y| x - y,
1392 Rational32::from_integer(100), 50 => Rational32::from_integer(50),
1393 Rational32::from_integer(100), i32::MIN as i64 => 100.0 - i32::MIN as f64,
1394 Rational32::from_integer(100), i32_overflow => 100.0 - i32_overflow as f64,
1395 Rational32::from_integer(100), 50.0 => 50.0,
1396 Rational32::from_integer(100), BigInt::from(50) => BigInt::from(50),
1397 Rational32::new(1, 2), BigInt::from(50) => -49.5,
1398 Rational32::from_integer(100), Rational32::from_integer(50) => Rational32::from_integer(50),
1399 Rational32::from_integer(i32::MIN), Rational32::from_integer(1) => i32::MIN as f64 - 1_f64
1400 ];
1401 }
1402
1403 #[test]
1404 fn div() {
1405 let i32_uflow = i32::MIN as i64 - 1;
1406 let i32_oflow = i32::MAX as i64 + 1;
1407
1408 verify![|x, y| x / y,
1410 100, 50 => Rational32::from_integer(2),
1411 i32_uflow, i32_uflow => 1.0,
1412 i32_oflow, i32_oflow => 1.0,
1413 100, BigInt::from(50) => Rational32::from_integer(2),
1414 i32_oflow, BigInt::from(i32_oflow) => 1.0,
1415 i32_oflow, BigInt::from(2) => i32_oflow as f64 / 2_f64,
1416 100, Rational32::from_integer(50) => Rational32::from_integer(2),
1417 100, Rational32::new(1, 2) => Rational32::from_integer(200),
1418 i32_oflow, Rational32::from_integer(2) => i32_oflow as f64 / 2_f64,
1419 i32::MAX as i64, Rational32::new(1, 2) => i32::MAX as f64 * 2.0,
1420 -100, 1.0 => -100.0
1421 ];
1422
1423 verify![|x, y| x / y,
1425 BigInt::from(100), 50 => Rational32::from_integer(2),
1426 BigInt::from(i32_oflow), 2 => i32_oflow as f64 / 2_f64,
1427 BigInt::from(100), i32_oflow => 100 as f64 / i32_oflow as f64,
1428 BigInt::from(100), BigInt::from(50) => Rational32::from_integer(2),
1429 BigInt::from(i32_oflow), BigInt::from(100) => i32_oflow as f64 / 100_f64,
1430 BigInt::from(100), BigInt::from(i32_oflow) => 100_f64 / i32_oflow as f64,
1431 BigInt::from(100), 50.0 => 2.0,
1432 BigInt::from(100), Rational32::from_integer(50) => Rational32::from_integer(2),
1433 BigInt::from(i32_oflow), Rational32::from_integer(50) => i32_oflow as f64 / 50_f64,
1434 BigInt::from(i32::MAX), Rational32::new(1, 2) => Number::from(i32::MAX as f64 * 2_f64)
1435 ];
1436
1437 verify![|x, y| x / y,
1439 100.0, 50 => 2.0,
1440 100.0, 50.0 => 2.0,
1441 100.0, BigInt::from(50) => 2.0,
1442 100.0, Rational32::from_integer(50) => 2.0,
1443 100.0, Rational32::new(1, 2) => 200.0
1444 ];
1445
1446 verify![|x, y| x / y,
1448 Rational32::from_integer(100), 50 => Rational32::from_integer(2),
1449 Rational32::from_integer(100), i32_oflow => 100_f64 / i32_oflow as f64,
1450 Rational32::from_integer(100), 50_f64 => 2_f64,
1451 Rational32::from_integer(100), BigInt::from(50) => Rational32::from_integer(2),
1452 Rational32::from_integer(100), BigInt::from(i32_oflow) => 100_f64 / i32_oflow as f64,
1453 Rational32::from_integer(100), Rational32::from_integer(50) => Rational32::from_integer(2),
1454 Rational32::from_integer(i32::MAX), Rational32::new(1,2) => i32::MAX as f64 * 2.0
1455 ];
1456 }
1457
1458 #[test]
1459 fn rem() {
1460 assert_eq!(Number::from(100) % Number::from(70), Some(Number::from(30)));
1462 assert_eq!(
1463 Number::from(100) % Number::from(BigInt::from(70)),
1464 Some(Number::from(30))
1465 );
1466 assert_eq!(
1467 Number::from(100) % Number::from(BigInt::from(i64::MAX) + BigInt::from(i64::MAX)),
1468 Some(Number::from(BigInt::from(100)))
1469 );
1470 assert_eq!(
1471 Number::from(100) % Number::from(1.0),
1472 Some(Number::Float(0.0))
1473 );
1474 assert_eq!(
1475 Number::from(100) % Number::from(Rational32::from_integer(70)),
1476 Some(Number::from(30))
1477 );
1478 assert_eq!(
1479 Number::from(100) % Number::from(Rational32::new(1, 2)),
1480 Some(Number::from(0))
1481 );
1482 assert_eq!(
1483 Number::from(1) % Number::from(Rational32::new(2, 5)),
1484 Some(Number::from(Rational32::new(1, 5)))
1485 );
1486 assert_eq!(
1487 Number::from(1) % Number::from(Rational32::new(3, 5)),
1488 Some(Number::from(Rational32::new(2, 5)))
1489 );
1490
1491 assert_eq!(
1493 Number::from(BigInt::from(100)) % Number::from(70),
1494 Some(Number::from(30))
1495 );
1496 assert_eq!(
1497 Number::from(BigInt::from(100)) % Number::from(BigInt::from(70)),
1498 Some(Number::from(BigInt::from(30)))
1499 );
1500 assert_eq!(Number::from(BigInt::from(100)) % Number::from(1.0), None);
1502 assert_eq!(
1503 Number::from(BigInt::from(100)) % Number::from(Rational32::from_integer(70)),
1504 Some(Number::from(BigInt::from(30)))
1505 );
1506 assert_eq!(
1507 Number::from(BigInt::from(1)) % Number::from(Rational32::new(2, 3)),
1508 Some(Number::from(Rational32::new(1, 3)))
1509 );
1510
1511 assert_eq!(
1513 Number::from(Rational32::from_integer(100)) % Number::from(70),
1514 Some(Number::from(30))
1515 );
1516 assert_eq!(
1517 Number::from(Rational32::from_integer(100)) % Number::from(BigInt::from(70)),
1518 Some(Number::from(BigInt::from(30)))
1519 );
1520 assert_eq!(
1521 Number::from(Rational32::from_integer(100))
1522 % Number::from(Rational32::from_integer(70)),
1523 Some(Number::from(Rational32::from_integer(30)))
1524 );
1525 assert_eq!(
1526 Number::from(Rational32::from_integer(1)) % Number::from(Rational32::new(2, 3)),
1527 Some(Number::from(Rational32::new(1, 3)))
1528 );
1529
1530 assert_eq!(
1532 Number::from(0.5) % Number::from(70),
1533 Some(Number::from(0.5))
1534 );
1535 assert_eq!(
1536 Number::from(100.0) % Number::from(70),
1537 Some(Number::from(30.0))
1538 );
1539 assert!((Number::from(f64::INFINITY) % Number::from(70))
1540 .unwrap()
1541 .to_f64()
1542 .unwrap()
1543 .is_nan());
1544 assert_eq!(
1545 Number::from(100.0) % Number::from(BigInt::from(70)),
1546 Some(Number::from(30.0))
1547 );
1548 assert_eq!(
1549 Number::from(100.0) % Number::from(BigInt::from(i64::MAX) + BigInt::from(i64::MAX)),
1550 Some(Number::from(100.0))
1551 );
1552 assert_eq!(
1553 Number::from(101.0) % Number::from(2.0),
1554 Some(Number::from(1.0))
1555 );
1556 assert_eq!(
1557 Number::from(100.0) % Number::from(Rational32::from_integer(70)),
1558 Some(Number::from(30.0))
1559 );
1560 assert_eq!(
1561 Number::from(100.0) % Number::from(Rational32::new(1, 2)),
1562 Some(Number::from(0.0))
1563 );
1564 assert_eq!(
1565 Number::from(0.75) % Number::from(Rational32::new(1, 2)),
1566 Some(Number::from(0.25))
1567 );
1568 }
1569
1570 #[test]
1571 fn modulo() {
1572 assert_eq!(
1573 Number::from(-21).modulo(&Number::from(4)),
1574 Some(Number::from(3))
1575 );
1576 }
1577
1578 #[test]
1579 fn round() {
1580 assert_eq!(Number::from(-4.3).floor(), Number::from(-5));
1581 assert_eq!(Number::from(-4.3).ceil(), Number::from(-4));
1582 assert_eq!(Number::from(-4.3).truncate(), Number::from(-4));
1583 assert_eq!(Number::from(-4.3).round(), Number::from(-4));
1584
1585 assert_eq!(Number::from(3.5).floor(), Number::from(3));
1586 assert_eq!(Number::from(3.5).ceil(), Number::from(4));
1587 assert_eq!(Number::from(3.5).truncate(), Number::from(3));
1588 assert_eq!(Number::from(3.5).round(), Number::from(4));
1589
1590 assert_eq!(Number::from(Rational32::new(7, 2)).round(), Number::from(4));
1591 }
1592
1593 #[test]
1594 fn abs() {
1595 assert_eq!(Number::from(-10).abs(), Number::from(10));
1596 assert_eq!(
1597 Number::from(i64::MIN).abs(),
1598 Number::from(BigInt::from(9223372036854775808_u64))
1599 );
1600 }
1601
1602 #[test]
1603 fn sin() {
1604 assert_eq!(Number::from(0).sin(), Some(Number::from(0)));
1605 assert_eq!(
1606 Number::from(f64::FRAC_PI_2()).sin(),
1607 Some(Number::from(1.0))
1608 );
1609 assert_eq!(
1610 Number::from(Rational32::from_integer(0)).sin(),
1611 Some(Number::from(0.0))
1612 );
1613 assert_eq!(Number::from(BigInt::from(0)).sin(), Some(Number::from(0.0)));
1614 assert!(Number::from(BigInt::from_f64(f64::MAX).unwrap() * 2)
1615 .sin()
1616 .unwrap()
1617 .to_f64()
1618 .unwrap()
1619 .is_nan());
1620 }
1621}