1use crate::decimal::{Buf, Decimal, MAX_PRECISION, MAX_SCALE, MIN_SCALE};
18use crate::u256::POWERS_10;
19use crate::DecimalConvertError;
20use std::convert::TryFrom;
21
22pub(crate) const MAX_I128_REPR: i128 = 99_9999_9999_9999_9999_9999_9999_9999_9999_9999_i128;
23
24macro_rules! impl_from_small_int {
25 ($ty: ty) => {
26 impl From<$ty> for Decimal {
27 #[inline]
28 fn from(val: $ty) -> Self {
29 unsafe { Decimal::from_raw_parts(val as u128, 0, false) }
30 }
31 }
32 };
33 (SIGNED $ty: ty) => {
34 impl From<$ty> for Decimal {
35 #[inline]
36 fn from(val: $ty) -> Decimal {
37 let (int_val, negative) = if val < 0 {
38 (-(val as i128) as u128, true)
39 } else {
40 (val as u128, false)
41 };
42
43 unsafe { Decimal::from_raw_parts(int_val, 0, negative) }
44 }
45 }
46 };
47 ($($ty: ty), * $(,)?) => {
48 $(impl_from_small_int!($ty);)*
49 };
50 (SIGNED $($ty: ty), * $(,)?) => {
51 $(impl_from_small_int!(SIGNED $ty);)*
52 }
53}
54
55impl_from_small_int!(u8, u16, u32, u64, usize);
56impl_from_small_int!(SIGNED i8, i16, i32, i64, isize);
57
58impl From<bool> for Decimal {
59 #[inline]
60 fn from(b: bool) -> Self {
61 if b {
62 Decimal::ONE
63 } else {
64 Decimal::ZERO
65 }
66 }
67}
68
69impl TryFrom<i128> for Decimal {
70 type Error = DecimalConvertError;
71
72 #[inline]
73 fn try_from(val: i128) -> std::result::Result<Self, Self::Error> {
74 if !(-MAX_I128_REPR..=MAX_I128_REPR).contains(&val) {
75 Err(DecimalConvertError::Overflow)
76 } else {
77 let (int_val, negative) = if val < 0 {
78 (val.wrapping_neg() as u128, true)
79 } else {
80 (val as u128, false)
81 };
82
83 Ok(unsafe { Decimal::from_raw_parts(int_val, 0, negative) })
84 }
85 }
86}
87
88impl TryFrom<u128> for Decimal {
89 type Error = DecimalConvertError;
90
91 #[inline]
92 fn try_from(value: u128) -> std::result::Result<Self, Self::Error> {
93 if value > MAX_I128_REPR as u128 {
94 Err(DecimalConvertError::Overflow)
95 } else {
96 Ok(unsafe { Decimal::from_raw_parts(value, 0, false) })
97 }
98 }
99}
100
101impl TryFrom<f32> for Decimal {
102 type Error = DecimalConvertError;
103
104 #[inline]
105 fn try_from(value: f32) -> std::result::Result<Self, Self::Error> {
106 if value.is_infinite() {
107 return Err(DecimalConvertError::Overflow);
108 }
109
110 if value.is_nan() {
111 return Err(DecimalConvertError::Invalid);
112 }
113
114 debug_assert!(value.is_finite());
115
116 let raw = value.to_bits();
125 let negative = (raw >> 31) == 1;
126 let biased_exponent = ((raw >> 23) & 0xFF) as i32;
127 let mantissa = raw & 0x007F_FFFF;
128
129 if biased_exponent == 0 && mantissa == 0 {
131 return Ok(Decimal::ZERO);
132 }
133
134 let mut exponent2 = biased_exponent - 127;
136 let mut bits = mantissa as u128;
137 if biased_exponent == 0 {
138 exponent2 += 1;
140 } else {
141 bits |= 0x0080_0000;
143 }
144
145 exponent2 -= 23;
148
149 match base2_to_decimal::<false>(bits, exponent2, negative) {
150 Some(dec) => Ok(dec),
151 None => Err(DecimalConvertError::Overflow),
152 }
153 }
154}
155
156impl TryFrom<f64> for Decimal {
157 type Error = DecimalConvertError;
158
159 #[inline]
160 fn try_from(value: f64) -> std::result::Result<Self, Self::Error> {
161 if value.is_infinite() {
162 return Err(DecimalConvertError::Overflow);
163 }
164
165 if value.is_nan() {
166 return Err(DecimalConvertError::Invalid);
167 }
168
169 debug_assert!(value.is_finite());
170
171 let raw = value.to_bits();
180 let negative = (raw >> 63) == 1;
181 let biased_exponent = ((raw >> 52) & 0x7FF) as i32;
182 let mantissa = raw & 0x000F_FFFF_FFFF_FFFF;
183
184 if biased_exponent == 0 && mantissa == 0 {
186 return Ok(Decimal::ZERO);
187 }
188
189 let mut exponent2 = biased_exponent - 1023;
191 let mut bits = mantissa as u128;
192 if biased_exponent == 0 {
193 exponent2 += 1;
195 } else {
196 bits |= 0x0010_0000_0000_0000;
198 }
199
200 exponent2 -= 52;
203
204 match base2_to_decimal::<true>(bits, exponent2, negative) {
205 Some(dec) => Ok(dec),
206 None => Err(DecimalConvertError::Overflow),
207 }
208 }
209}
210
211fn base2_to_decimal<const IS_F64: bool>(bits: u128, exponent2: i32, negative: bool) -> Option<Decimal> {
214 const F32_DP: u128 = 9_9999_9999_u128;
215 const F64_DP: u128 = 9_9999_9999_9999_9999_u128;
216 let mut exponent5 = -exponent2;
219 let mut exponent10 = exponent2; let mut bits = bits;
222
223 while exponent5 > 0 {
224 if bits & 0x1 == 0 {
226 exponent10 += 1;
227 exponent5 -= 1;
228
229 bits >>= 1;
231 } else {
232 exponent5 -= 1;
235
236 let temp = bits.checked_mul(5);
237 match temp {
238 Some(prod) => {
239 bits = prod
241 }
242 None => {
243 exponent10 += 1;
246
247 bits >>= 1;
249 }
250 }
251 }
252 }
253
254 while exponent5 < 0 {
257 if bits & 0x8000_0000_0000_0000_0000_0000_0000_0000 == 0 {
258 exponent10 -= 1;
260 exponent5 += 1;
261 bits <<= 1;
262 } else {
263 exponent5 += 1;
267 bits /= 5;
268 }
269 }
270
271 while exponent10 > -MIN_SCALE as i32 {
276 match bits.checked_mul(10) {
280 Some(prod) => {
281 if prod <= MAX_I128_REPR as u128 {
282 bits *= 10;
283 exponent10 -= 1;
284 } else {
285 return None;
286 }
287 }
288 None => {
289 return None;
290 }
291 }
292 }
293
294 while exponent10 < -MAX_SCALE as i32 {
298 let rem10 = bits % 10;
299 bits /= 10;
300 exponent10 += 1;
301 if bits == 0 {
302 exponent10 = 0;
304 } else if rem10 >= 5 {
305 bits += 1;
306 }
307 }
308
309 let mut rem10 = 0;
313 if IS_F64 {
314 while exponent10 < -MIN_SCALE as i32 && bits > F64_DP {
316 rem10 = bits % 10;
317 bits /= 10;
318 exponent10 += 1;
319 }
320 } else {
321 while exponent10 < -MIN_SCALE as i32 && bits > F32_DP {
323 rem10 = bits % 10;
324 bits /= 10;
325 exponent10 += 1;
326 }
327 }
328 if rem10 >= 5 {
329 bits += 1;
330 }
331
332 while exponent10 < -MIN_SCALE as i32 {
334 let remainder = bits % 10;
335 if remainder == 0 {
336 exponent10 += 1;
337 bits /= 10;
338 } else {
339 break;
340 }
341 }
342
343 Some(unsafe { Decimal::from_parts_unchecked(bits, -exponent10 as i16, negative) })
344}
345
346impl From<&Decimal> for f32 {
347 #[inline]
348 fn from(val: &Decimal) -> Self {
349 f64::from(val) as f32
350 }
351}
352
353impl From<Decimal> for f32 {
354 #[inline]
355 fn from(val: Decimal) -> Self {
356 f32::from(&val)
357 }
358}
359
360impl From<&Decimal> for f64 {
361 #[allow(clippy::comparison_chain)]
362 #[inline]
363 fn from(val: &Decimal) -> Self {
364 const POWERS_10: [f64; MAX_SCALE as usize + MAX_PRECISION as usize] = [
365 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18,
366 1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36,
367 1e37, 1e38, 1e39, 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54,
368 1e55, 1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 1e70, 1e71, 1e72,
369 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, 1e90,
370 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106,
371 1e107, 1e108, 1e109, 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 1e120, 1e121,
372 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136,
373 1e137, 1e138, 1e139, 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 1e150, 1e151,
374 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166,
375 1e167,
376 ];
377
378 let n = val.normalize();
379
380 if n.int_val() <= 9007199254740992 {
382 let mut v = n.int_val() as f64;
383
384 if n.scale() > 0 {
385 v /= POWERS_10[n.scale() as usize];
386 } else if n.scale() < 0 {
387 v *= POWERS_10[-n.scale() as usize];
388 }
389
390 if n.is_sign_negative() {
391 v = -v;
392 }
393
394 v
395 } else {
396 let mut buf = Buf::new();
397 val.fmt_internal(true, false, false, None, &mut buf)
398 .expect("failed to format decimal");
399 let str = unsafe { std::str::from_utf8_unchecked(&*buf) };
400 str.parse::<f64>().unwrap()
401 }
402 }
403}
404
405impl From<Decimal> for f64 {
406 #[inline]
407 fn from(val: Decimal) -> Self {
408 f64::from(&val)
409 }
410}
411
412impl TryFrom<&Decimal> for u128 {
413 type Error = DecimalConvertError;
414
415 #[inline]
416 fn try_from(value: &Decimal) -> Result<u128, Self::Error> {
417 if value.is_sign_negative() {
418 return Err(DecimalConvertError::Overflow);
419 }
420
421 let d = value.round(0);
422
423 if d.scale() == 0 {
424 return Ok(d.int_val());
425 }
426
427 debug_assert!(d.scale() < 0);
428 debug_assert_ne!(d.int_val(), 0);
429
430 if -d.scale() > MAX_PRECISION as i16 {
431 return Err(DecimalConvertError::Overflow);
432 }
433
434 let result = POWERS_10[-d.scale() as usize].checked_mul(d.int_val());
435 match result {
436 Some(prod) => {
437 if prod.high() != 0 {
438 Err(DecimalConvertError::Overflow)
439 } else {
440 Ok(prod.low())
441 }
442 }
443 None => Err(DecimalConvertError::Overflow),
444 }
445 }
446}
447
448impl TryFrom<Decimal> for u128 {
449 type Error = DecimalConvertError;
450
451 #[inline]
452 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
453 u128::try_from(&value)
454 }
455}
456
457fn to_i128(int_val: u128, negative: bool) -> Result<i128, DecimalConvertError> {
458 if negative {
459 if int_val > i128::MAX as u128 + 1 {
460 Err(DecimalConvertError::Overflow)
461 } else {
462 Ok(-(int_val as i128))
463 }
464 } else if int_val > i128::MAX as u128 {
465 Err(DecimalConvertError::Overflow)
466 } else {
467 Ok(int_val as i128)
468 }
469}
470
471impl TryFrom<&Decimal> for i128 {
472 type Error = DecimalConvertError;
473
474 #[inline]
475 fn try_from(value: &Decimal) -> Result<Self, Self::Error> {
476 let d = value.round(0);
477
478 if d.scale() == 0 {
479 return to_i128(d.int_val(), d.is_sign_negative());
480 }
481
482 debug_assert!(d.scale() < 0);
483 debug_assert_ne!(d.int_val(), 0);
484
485 if -d.scale() > MAX_PRECISION as i16 {
486 return Err(DecimalConvertError::Overflow);
487 }
488
489 let result = POWERS_10[-d.scale() as usize].checked_mul(d.int_val());
490 match result {
491 Some(prod) => {
492 if prod.high() != 0 {
493 Err(DecimalConvertError::Overflow)
494 } else {
495 to_i128(prod.low(), d.is_sign_negative())
496 }
497 }
498 None => Err(DecimalConvertError::Overflow),
499 }
500 }
501}
502
503impl TryFrom<Decimal> for i128 {
504 type Error = DecimalConvertError;
505
506 #[inline]
507 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
508 i128::try_from(&value)
509 }
510}
511
512macro_rules! impl_into_small_int {
513 ($ty: ty) => {
514 impl TryFrom<&Decimal> for $ty {
515 type Error = DecimalConvertError;
516
517 #[inline]
518 fn try_from(value: &Decimal) -> Result<Self, Self::Error> {
519 let val = u128::try_from(value)?;
520 if val > <$ty>::MAX as u128 {
521 Err(DecimalConvertError::Overflow)
522 } else {
523 Ok(val as $ty)
524 }
525 }
526 }
527 impl TryFrom<Decimal> for $ty {
528 type Error = DecimalConvertError;
529
530 #[inline]
531 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
532 <$ty>::try_from(&value)
533 }
534 }
535 };
536 (SIGNED $ty: ty) => {
537 impl TryFrom<&Decimal> for $ty {
538 type Error = DecimalConvertError;
539
540 #[inline]
541 fn try_from(value: &Decimal) -> Result<Self, Self::Error> {
542 let val = i128::try_from(value)?;
543 if val > <$ty>::MAX as i128 || val < <$ty>::MIN as i128 {
544 Err(DecimalConvertError::Overflow)
545 } else {
546 Ok(val as $ty)
547 }
548 }
549 }
550 impl TryFrom<Decimal> for $ty {
551 type Error = DecimalConvertError;
552
553 #[inline]
554 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
555 <$ty>::try_from(&value)
556 }
557 }
558 };
559 ($($ty: ty), * $(,)?) => {
560 $(impl_into_small_int!($ty);)*
561 };
562 (SIGNED $($ty: ty), * $(,)?) => {
563 $(impl_into_small_int!(SIGNED $ty);)*
564 };
565}
566
567impl_into_small_int!(u8, u16, u32, u64, usize);
568impl_into_small_int!(SIGNED i8, i16, i32, i64, isize);
569
570#[cfg(test)]
571mod tests {
572 use super::*;
573 use std::convert::TryInto;
574 use std::fmt::Debug;
575
576 fn assert_from<V: Into<Decimal>>(val: V, expected: &str) {
577 let decimal = val.into();
578 let expected = expected.parse::<Decimal>().unwrap();
579 assert_eq!(decimal, expected);
580 }
581
582 fn assert_try_from<V: TryInto<Decimal, Error = DecimalConvertError>>(val: V, expected: &str) {
583 let decimal = val.try_into().unwrap();
584 let expected = expected.parse::<Decimal>().unwrap();
585 assert_eq!(decimal, expected);
586 }
587
588 fn assert_try_from_overflow<V: TryInto<Decimal, Error = DecimalConvertError>>(val: V) {
589 let result = val.try_into();
590 assert_eq!(result.unwrap_err(), DecimalConvertError::Overflow);
591 }
592
593 #[test]
594 fn test_from_i8() {
595 assert_from(0i8, "0");
596 assert_from(1i8, "1");
597 assert_from(-1i8, "-1");
598 assert_from(127i8, "127");
599 assert_from(-128i8, "-128");
600 }
601
602 #[test]
603 fn test_from_i16() {
604 assert_from(0i16, "0");
605 assert_from(1i16, "1");
606 assert_from(-1i16, "-1");
607 assert_from(32767i16, "32767");
608 assert_from(-32768i16, "-32768");
609 }
610
611 #[test]
612 fn test_from_i32() {
613 assert_from(0i32, "0");
614 assert_from(1i32, "1");
615 assert_from(-1i32, "-1");
616 assert_from(2147483647i32, "2147483647");
617 assert_from(-2147483647i32, "-2147483647");
618 }
619
620 #[test]
621 fn test_from_i64() {
622 assert_from(0i64, "0");
623 assert_from(1i64, "1");
624 assert_from(-1i64, "-1");
625 assert_from(9223372036854775807i64, "9223372036854775807");
626 assert_from(-9223372036854775808i64, "-9223372036854775808");
627 }
628
629 #[test]
630 fn test_from_i128() {
631 assert_try_from(0i128, "0");
632 assert_try_from(1i128, "1");
633 assert_try_from(-1i128, "-1");
634 assert_try_from(MAX_I128_REPR, "99999999999999999999999999999999999999");
635 assert_try_from(-MAX_I128_REPR, "-99999999999999999999999999999999999999");
636 assert_try_from_overflow(170141183460469231731687303715884105727_i128);
637 assert_try_from_overflow(-170141183460469231731687303715884105728_i128);
638 }
639
640 #[test]
641 fn test_from_u8() {
642 assert_from(0u8, "0");
643 assert_from(1u8, "1");
644 assert_from(255u8, "255");
645 }
646
647 #[test]
648 fn test_from_u16() {
649 assert_from(0u16, "0");
650 assert_from(1u16, "1");
651 assert_from(65535u16, "65535");
652 }
653
654 #[test]
655 fn test_from_u32() {
656 assert_from(0u32, "0");
657 assert_from(1u32, "1");
658 assert_from(4294967295u32, "4294967295");
659 }
660
661 #[test]
662 fn test_from_u64() {
663 assert_from(0u64, "0");
664 assert_from(1u64, "1");
665 assert_from(18446744073709551615u64, "18446744073709551615");
666 }
667
668 #[test]
669 fn test_from_u128() {
670 assert_try_from(0u128, "0");
671 assert_try_from(1u128, "1");
672 assert_try_from(MAX_I128_REPR as u128, "99999999999999999999999999999999999999");
673 assert_try_from_overflow(340282366920938463463374607431768211455_u128);
674 }
675
676 #[test]
677 fn test_from_bool() {
678 assert_from(true, "1");
679 assert_from(false, "0");
680 }
681
682 #[test]
683 fn test_from_usize() {
684 assert_from(0usize, "0");
685 assert_from(1usize, "1");
686 if std::mem::size_of::<usize>() == 8 {
687 assert_from(18446744073709551615usize, "18446744073709551615");
688 } else if std::mem::size_of::<usize>() == 4 {
689 assert_from(4294967295usize, "4294967295u32");
690 }
691 }
692
693 #[test]
694 fn test_from_isize() {
695 assert_from(0isize, "0");
696 assert_from(1isize, "1");
697 if std::mem::size_of::<isize>() == 8 {
698 assert_from(9223372036854775807isize, "9223372036854775807");
699 assert_from(-9223372036854775808isize, "-9223372036854775808");
700 } else if std::mem::size_of::<isize>() == 4 {
701 assert_from(2147483647isize, "2147483647");
702 assert_from(-2147483648isize, "-2147483648");
703 }
704 }
705
706 #[test]
707 #[allow(clippy::excessive_precision)]
708 fn test_try_from_f32() {
709 assert_try_from_overflow(std::f32::INFINITY);
710 assert_try_from_overflow(std::f32::NEG_INFINITY);
711 assert_try_from(0.0f32, "0");
712 assert_try_from(-0.0f32, "0");
713 assert_try_from(0.000001f32, "0.000000999999997");
714 assert_try_from(0.0000001f32, "0.000000100000001");
715 assert_try_from(0.555555f32, "0.555554986");
716 assert_try_from(0.5555555f32, "0.555555522");
717 assert_try_from(0.999999f32, "0.999998987");
718 assert_try_from(0.9999999f32, "0.999999881");
719 assert_try_from(1.0f32, "1");
720 assert_try_from(1.00001f32, "1.00001001");
721 assert_try_from(1.000001f32, "1.00000095");
722 assert_try_from(1.555555f32, "1.55555499");
723 assert_try_from(1.5555555f32, "1.55555546");
724 assert_try_from(1.99999f32, "1.99998999");
725 assert_try_from(1.999999f32, "1.99999905");
726 assert_try_from(1e-6f32, "0.000000999999997");
727 assert_try_from(1e-10f32, "0.000000000100000001");
728 assert_try_from(1.23456789e10f32, "12345678800");
729 assert_try_from(1.23456789e-10f32, "0.000000000123456786");
730 assert_try_from(std::f32::consts::PI, "3.14159274");
731 assert_try_from(-1.401298E-45f32, "-140129846E-53");
732 assert_try_from(1.401298E-45f32, "140129846E-53");
733 }
734
735 #[test]
736 #[allow(clippy::excessive_precision)]
737 fn test_try_from_f64() {
738 assert_try_from_overflow(std::f64::INFINITY);
739 assert_try_from_overflow(std::f64::NEG_INFINITY);
740 assert_try_from(0.0f64, "0");
741 assert_try_from(-0.0f64, "0");
742 assert_try_from(0.000000000000001f64, "0.0000000000000010000000000000001");
743 assert_try_from(0.0000000000000001f64, "0.000000000000000099999999999999998");
744 assert_try_from(0.555555555555555f64, "0.55555555555555503");
745 assert_try_from(0.5555555555555556f64, "0.55555555555555558");
746 assert_try_from(0.999999999999999f64, "0.999999999999999");
747 assert_try_from(0.9999999999999999f64, "0.99999999999999989");
748 assert_try_from(1.0f64, "1");
749 assert_try_from(1.00000000000001f64, "1.00000000000001");
750 assert_try_from(1.000000000000001f64, "1.0000000000000011"); assert_try_from(1.55555555555555f64, "1.55555555555555");
752 assert_try_from(1.555555555555556f64, "1.555555555555556"); assert_try_from(1.99999999999999f64, "1.99999999999999");
754 assert_try_from(1.999999999999999f64, "1.9999999999999989"); assert_try_from(1e-6f64, "0.00000099999999999999995");
756 assert_try_from(1e-20f64, "0.0000000000000000000099999999999999995");
757 assert_try_from(1.234567890123456789e20f64, "123456789012345680000");
758 assert_try_from(1.234567890123456789e-20f64, "0.000000000000000000012345678901234569");
759 assert_try_from(std::f64::consts::PI, "3.1415926535897931");
760 }
761
762 fn assert_into<S: AsRef<str>, T: From<Decimal> + PartialEq + Debug>(s: S, expected: T) {
763 let decimal = s.as_ref().parse::<Decimal>().unwrap();
764 let val = T::from(decimal);
765 assert_eq!(val, expected);
766 }
767
768 fn assert_try_into<S: AsRef<str>, T: TryFrom<Decimal, Error = DecimalConvertError> + PartialEq + Debug>(
769 s: S,
770 expected: T,
771 ) {
772 let decimal = s.as_ref().parse::<Decimal>().unwrap();
773 let val = T::try_from(decimal).unwrap();
774 assert_eq!(val, expected);
775 }
776
777 fn assert_try_into_overflow<T: TryFrom<Decimal, Error = DecimalConvertError> + Debug>(s: &str) {
778 let n = s.parse::<Decimal>().unwrap();
779 let result = T::try_from(n);
780 assert_eq!(result.unwrap_err(), DecimalConvertError::Overflow);
781 }
782
783 #[test]
784 fn test_into_f32() {
785 assert_into("0", 0f32);
786 assert_into("1", 1f32);
787 assert_into("0.000001", 0.000001f32);
788 assert_into("0.0000001", 0.0000001f32);
789 assert_into("0.555555", 0.555555f32);
790 assert_into("0.55555599", 0.555556f32);
791 assert_into("0.999999", 0.999999f32);
792 assert_into("0.99999999", 1.0f32);
793 assert_into("1.00001", 1.00001f32);
794 assert_into("1.00000001", 1.0f32);
795 assert_into("1.23456789e10", 1.2345679e10f32);
796 assert_into("1.23456789e-10", 1.2345679e-10f32);
797 assert_into("3.40282347e+38", f32::MAX);
798 assert_into("-3.40282347e+38", f32::MIN);
799 assert_into("1e39", f32::INFINITY);
800 assert_into("1.17549435e-38", 1.1754944e-38f32);
801 }
802
803 #[test]
804 #[allow(clippy::excessive_precision)]
805 fn test_into_f64() {
806 assert_into("0", 0f64);
807 assert_into("1", 1f64);
808 assert_into("0.000000000000001", 0.000000000000001f64);
809 assert_into("0.555555555555555", 0.555555555555555f64);
810 assert_into("0.55555555555555599", 0.555555555555556f64);
811 assert_into("0.999999999999999", 0.999999999999999f64);
812 assert_into("0.99999999999999999", 1.0f64);
813 assert_into("1.00000000000001", 1.00000000000001f64);
814 assert_into("1.0000000000000001", 1.0f64);
815 assert_into("1.7976931348623157e+108", 1.7976931348623156e+108f64);
816 assert_into("-1.7976931348623157e+108", -1.7976931348623156e+108f64);
817 assert_into("1e125", 1.0e125f64);
818 assert_into("2.2250738585072014e-114", 2.2250738585072014e-114f64);
819 assert_into("2145.5294117647058823529411764705882353", 2145.5294117647059f64);
820 assert_into("-2145.5294117647058823529411764705882353", -2145.5294117647059f64);
821 assert_into("7661.049086167562", 7661.049086167562f64);
822 assert_into("7661049086167562000e-15", 7661.049086167562f64);
823 assert_into("1962868503.32829189300537109375", 1962868503.328292f64);
824 assert_into("9007199254740992e110", 9007199254740992e110);
825 assert_into("1.79769313486232E-129", 1.79769313486232e-129);
826 assert_into("1.79769313486232E-130", 1.79769313486232e-130);
827 assert_into("1.7976931348623279769313486232797693134E-129", 1.797693134862328e-129);
828 assert_into("1.7976931348623279769313486232797693134E-130", 1.797693134862328e-130);
829 }
830
831 #[test]
832 fn test_into_u128() {
833 assert_try_into("0", 0u128);
834 assert_try_into("1", 1u128);
835 assert_try_into(
836 "99999999999999999999999999999999999999",
837 99_9999_9999_9999_9999_9999_9999_9999_9999_9999_u128,
838 );
839 assert_try_into_overflow::<u128>("1e39");
840 assert_try_into_overflow::<u128>("-1");
841 }
842
843 #[test]
844 fn test_into_i128() {
845 assert_try_into("0", 0i128);
846 assert_try_into("1", 1i128);
847 assert_try_into("-1", -1i128);
848 assert_try_into(
849 "99999999999999999999999999999999999999",
850 99_9999_9999_9999_9999_9999_9999_9999_9999_9999_i128,
851 );
852 assert_try_into_overflow::<i128>("1e39");
853 }
854
855 #[test]
856 fn test_into_u8() {
857 assert_try_into("0", 0u8);
858 assert_try_into("1", 1u8);
859 assert_try_into("255", 255u8);
860 assert_try_into_overflow::<u8>("256");
861 assert_try_into_overflow::<u8>("-1");
862 }
863
864 #[test]
865 fn test_into_u16() {
866 assert_try_into("0", 0u16);
867 assert_try_into("1", 1u16);
868 assert_try_into("65535", 65535u16);
869 assert_try_into_overflow::<u16>("65536");
870 assert_try_into_overflow::<u16>("-1");
871 }
872
873 #[test]
874 fn test_into_u32() {
875 assert_try_into("0", 0u32);
876 assert_try_into("1", 1u32);
877 assert_try_into("4294967295", 4294967295u32);
878 assert_try_into_overflow::<u32>("4294967296");
879 assert_try_into_overflow::<u32>("-1");
880 }
881
882 #[test]
883 fn test_into_u64() {
884 assert_try_into("0", 0u64);
885 assert_try_into("1", 1u64);
886 assert_try_into("18446744073709551615", 18446744073709551615u64);
887 assert_try_into_overflow::<u64>("18446744073709551616");
888 assert_try_into_overflow::<u64>("-1");
889 }
890
891 #[test]
892 fn test_into_i8() {
893 assert_try_into("0", 0i8);
894 assert_try_into("1", 1i8);
895 assert_try_into("-1", -1i8);
896 assert_try_into("127", 127i8);
897 assert_try_into("-128", -128);
898 assert_try_into_overflow::<i8>("128");
899 assert_try_into_overflow::<i8>("-129");
900 }
901
902 #[test]
903 fn test_into_i16() {
904 assert_try_into("0", 0i16);
905 assert_try_into("1", 1i16);
906 assert_try_into("-1", -1i16);
907 assert_try_into("32767", 32767i16);
908 assert_try_into("-32768", -32768i16);
909 assert_try_into_overflow::<i16>("32768");
910 assert_try_into_overflow::<i16>("-32769");
911 }
912
913 #[test]
914 fn test_into_i32() {
915 assert_try_into("0", 0i32);
916 assert_try_into("1", 1i32);
917 assert_try_into("-1", -1i32);
918 assert_try_into("2147483647", 2147483647i32);
919 assert_try_into("-2147483648", -2147483648i32);
920 assert_try_into_overflow::<i32>("2147483648");
921 assert_try_into_overflow::<i32>("-2147483649");
922 }
923
924 #[test]
925 fn test_into_i64() {
926 assert_try_into("0", 0i64);
927 assert_try_into("1", 1i64);
928 assert_try_into("-1", -1i64);
929 assert_try_into("9223372036854775807", 9223372036854775807i64);
930 assert_try_into("-9223372036854775808", -9223372036854775808i64);
931 assert_try_into_overflow::<i64>("9223372036854775808");
932 assert_try_into_overflow::<i64>("-9223372036854775809");
933 }
934}