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