1use crate::{
17 display::Mul10,
18 helpers::IntHelper,
19 types::extra::{False, LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8},
20 wide_div::WideDivRem,
21 FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
22 FixedU8,
23};
24use core::{
25 cmp::Ordering,
26 fmt::{Display, Formatter, Result as FmtResult},
27 ops::{Add, Mul, Shl, Shr},
28 str::FromStr,
29};
30#[cfg(feature = "std")]
31use std::error::Error;
32
33fn bin_str_int_to_bin<I>(bytes: &[u8]) -> (I, bool)
34where
35 I: IntHelper<IsSigned = False> + From<u8>,
36{
37 let max_len = I::NBITS as usize;
38 let (bytes, overflow) = if bytes.len() > max_len {
39 (&bytes[(bytes.len() - max_len)..], true)
40 } else {
41 (bytes, false)
42 };
43 let mut acc = I::from(0);
44 for &byte in bytes {
45 acc = (acc << 1) + I::from(byte - b'0');
46 }
47 (acc, overflow)
48}
49
50fn bin_str_frac_to_bin<I>(bytes: &[u8], nbits: u32) -> Option<I>
51where
52 I: IntHelper<IsSigned = False> + From<u8>,
53 I: Shl<u32, Output = I> + Shr<u32, Output = I> + Add<Output = I>,
54{
55 debug_assert!(!bytes.is_empty());
56 let dump_bits = I::NBITS - nbits;
57 let mut rem_bits = nbits;
58 let mut acc = I::ZERO;
59 for (i, &byte) in bytes.iter().enumerate() {
60 let val = byte - b'0';
61 if rem_bits < 1 {
62 if val != 0 {
63 if bytes.len() > i + 1 || acc.is_odd() {
66 acc = acc.checked_add(I::from(1))?;
67 }
68 }
69 if dump_bits != 0 && acc >> nbits != I::ZERO {
70 return None;
71 }
72 return Some(acc);
73 }
74 acc = (acc << 1) + I::from(val);
75 rem_bits -= 1;
76 }
77 Some(acc << rem_bits)
78}
79
80fn oct_str_int_to_bin<I>(bytes: &[u8]) -> (I, bool)
81where
82 I: IntHelper<IsSigned = False> + From<u8>,
83{
84 let max_len = (I::NBITS as usize + 2) / 3;
85 let (bytes, mut overflow) = if bytes.len() > max_len {
86 (&bytes[(bytes.len() - max_len)..], true)
87 } else {
88 (bytes, false)
89 };
90 let mut acc = I::from(bytes[0] - b'0');
91 if bytes.len() == max_len {
92 let first_max_bits = I::NBITS - (max_len as u32 - 1) * 3;
93 let first_max = (I::from(1) << first_max_bits) - I::from(1);
94 if acc > first_max {
95 overflow = true;
96 }
97 }
98 for &byte in &bytes[1..] {
99 acc = (acc << 3) + I::from(byte - b'0');
100 }
101 (acc, overflow)
102}
103
104fn oct_str_frac_to_bin<I>(bytes: &[u8], nbits: u32) -> Option<I>
105where
106 I: IntHelper<IsSigned = False> + From<u8>,
107 I: Shl<u32, Output = I> + Shr<u32, Output = I> + Add<Output = I>,
108{
109 debug_assert!(!bytes.is_empty());
110 let dump_bits = I::NBITS - nbits;
111 let mut rem_bits = nbits;
112 let mut acc = I::ZERO;
113 for (i, &byte) in bytes.iter().enumerate() {
114 let val = byte - b'0';
115 if rem_bits < 3 {
116 acc = (acc << rem_bits) + I::from(val >> (3 - rem_bits));
117 let half = 1 << (2 - rem_bits);
118 if val & half != 0 {
119 if val & (half - 1) != 0 || bytes.len() > i + 1 || acc.is_odd() {
122 acc = acc.checked_add(I::from(1))?;
123 }
124 }
125 if dump_bits != 0 && acc >> nbits != I::ZERO {
126 return None;
127 }
128 return Some(acc);
129 }
130 acc = (acc << 3) + I::from(val);
131 rem_bits -= 3;
132 }
133 Some(acc << rem_bits)
134}
135
136fn unchecked_hex_digit(byte: u8) -> u8 {
137 (byte & 0x0f) + if byte >= 0x40 { 9 } else { 0 }
142}
143
144fn hex_str_int_to_bin<I>(bytes: &[u8]) -> (I, bool)
145where
146 I: IntHelper<IsSigned = False> + From<u8>,
147{
148 let max_len = (I::NBITS as usize + 3) / 4;
149 let (bytes, mut overflow) = if bytes.len() > max_len {
150 (&bytes[(bytes.len() - max_len)..], true)
151 } else {
152 (bytes, false)
153 };
154 let mut acc = I::from(unchecked_hex_digit(bytes[0]));
155 if bytes.len() == max_len {
156 let first_max_bits = I::NBITS - (max_len as u32 - 1) * 4;
157 let first_max = (I::from(1) << first_max_bits) - I::from(1);
158 if acc > first_max {
159 overflow = true;
160 }
161 }
162 for &byte in &bytes[1..] {
163 acc = (acc << 4) + I::from(unchecked_hex_digit(byte));
164 }
165 (acc, overflow)
166}
167
168fn hex_str_frac_to_bin<I>(bytes: &[u8], nbits: u32) -> Option<I>
169where
170 I: IntHelper<IsSigned = False> + From<u8>,
171 I: Shl<u32, Output = I> + Shr<u32, Output = I> + Add<Output = I>,
172{
173 debug_assert!(!bytes.is_empty());
174 let dump_bits = I::NBITS - nbits;
175 let mut rem_bits = nbits;
176 let mut acc = I::ZERO;
177 for (i, &byte) in bytes.iter().enumerate() {
178 let val = unchecked_hex_digit(byte);
179 if rem_bits < 4 {
180 acc = (acc << rem_bits) + I::from(val >> (4 - rem_bits));
181 let half = 1 << (3 - rem_bits);
182 if val & half != 0 {
183 if val & (half - 1) != 0 || bytes.len() > i + 1 || acc.is_odd() {
186 acc = acc.checked_add(I::from(1))?;
187 }
188 }
189 if dump_bits != 0 && acc >> nbits != I::ZERO {
190 return None;
191 }
192 return Some(acc);
193 }
194 acc = (acc << 4) + I::from(val);
195 rem_bits -= 4;
196 }
197 Some(acc << rem_bits)
198}
199
200fn dec_str_int_to_bin<I>(bytes: &[u8]) -> (I, bool)
201where
202 I: IntHelper<IsSigned = False> + From<u8>,
203{
204 let max_effective_len = I::NBITS as usize;
205 let (bytes, mut overflow) = if bytes.len() > max_effective_len {
206 (&bytes[(bytes.len() - max_effective_len)..], true)
207 } else {
208 (bytes, false)
209 };
210 let mut acc = I::from(0);
211 for &byte in bytes {
212 let (mul, mul_overflow) = acc.overflowing_mul(I::from(10));
213 let (add, add_overflow) = mul.overflowing_add(I::from(byte - b'0'));
214 acc = add;
215 overflow = overflow || mul_overflow || add_overflow;
216 }
217 (acc, overflow)
218}
219
220enum Round {
221 Nearest,
222 Floor,
223}
224
225trait DecToBin: Sized {
279 type Double;
280 fn dec_to_bin(val: Self::Double, nbits: u32, round: Round) -> Option<Self>;
281 fn parse_is_short(bytes: &[u8]) -> (Self::Double, bool);
282}
283
284macro_rules! impl_dec_to_bin {
285 ($Single:ident, $Double:ident, $dec:expr, $bin:expr) => {
286 impl DecToBin for $Single {
287 type Double = $Double;
288 fn dec_to_bin(val: $Double, nbits: u32, round: Round) -> Option<$Single> {
289 debug_assert!(val < $Double::pow(10, $dec));
290 debug_assert!(nbits <= $bin);
291 let fives = $Double::pow(5, $dec);
292 let denom = fives * 2;
293 let mut numer = val << ($bin - $dec + 1) >> ($bin - nbits);
294 match round {
295 Round::Nearest => {
296 numer += fives;
298 if numer >> nbits >= denom {
302 return if nbits == 0 && val == fives << ($dec - 1) {
304 Some(0)
305 } else {
306 None
307 };
308 }
309 }
310 Round::Floor => {}
311 }
312 let (mut div, tie) = (numer / denom, numer % denom == 0);
313 if tie && div.is_odd() {
314 div -= 1;
315 }
316 Some(div as $Single)
317 }
318
319 fn parse_is_short(bytes: &[u8]) -> ($Double, bool) {
320 let (is_short, slice, pad) =
321 if let Some(rem) = usize::checked_sub($dec, bytes.len()) {
322 (true, bytes, $Double::pow(10, rem as u32))
323 } else {
324 (false, &bytes[..$dec], 1)
325 };
326 let val = dec_str_int_to_bin::<$Double>(slice).0 * pad;
327 (val, is_short)
328 }
329 }
330 };
331}
332impl_dec_to_bin! { u8, u16, 3, 8 }
333impl_dec_to_bin! { u16, u32, 6, 16 }
334impl_dec_to_bin! { u32, u64, 13, 32 }
335impl_dec_to_bin! { u64, u128, 27, 64 }
336
337impl DecToBin for u128 {
338 type Double = (u128, u128);
339 fn dec_to_bin((hi, lo): (u128, u128), nbits: u32, round: Round) -> Option<u128> {
340 debug_assert!(hi < 10u128.pow(27));
341 debug_assert!(lo < 10u128.pow(27));
342 debug_assert!(nbits <= 128);
343 let fives = 5u128.pow(54);
344 let denom = fives * 2;
345 let (hi_hi, hi_lo) = mul_hi_lo(hi, 10u128.pow(27));
347 let (val_lo, overflow) = hi_lo.overflowing_add(lo);
348 let val_hi = if overflow { hi_hi + 1 } else { hi_hi };
349 let (mut numer_lo, mut numer_hi) = (val_lo, val_hi);
350 match nbits.cmp(&(54 - 1)) {
351 Ordering::Less => {
352 let shr = (54 - 1) - nbits;
353 numer_lo = (numer_lo >> shr) | (numer_hi << (128 - shr));
354 numer_hi >>= shr;
355 }
356 Ordering::Greater => {
357 let shl = nbits - (54 - 1);
358 numer_hi = (numer_hi << shl) | (numer_lo >> (128 - shl));
359 numer_lo <<= shl;
360 }
361 Ordering::Equal => {}
362 };
363 match round {
364 Round::Nearest => {
365 let (wrapped, overflow) = numer_lo.overflowing_add(fives);
367 numer_lo = wrapped;
368 if overflow {
369 numer_hi += 1;
370 }
371 let check_overflow = if nbits == 128 {
372 numer_hi
373 } else if nbits == 0 {
374 numer_lo
375 } else {
376 (numer_lo >> nbits) | (numer_hi << (128 - nbits))
377 };
378 if check_overflow >= denom {
382 let half_hi = fives >> (128 - (54 - 1));
384 let half_lo = fives << (54 - 1);
385 return if nbits == 0 && val_hi == half_hi && val_lo == half_lo {
386 Some(0)
387 } else {
388 None
389 };
390 }
391 }
392 Round::Floor => {}
393 }
394 let (mut div, tie) = div_tie(numer_hi, numer_lo, denom);
395 if tie && div.is_odd() {
396 div -= 1;
397 }
398 Some(div)
399 }
400
401 fn parse_is_short(bytes: &[u8]) -> ((u128, u128), bool) {
402 if let Some(rem) = 27usize.checked_sub(bytes.len()) {
403 let hi = dec_str_int_to_bin::<u128>(bytes).0 * 10u128.pow(rem as u32);
404 ((hi, 0), true)
405 } else {
406 let hi = dec_str_int_to_bin::<u128>(&bytes[..27]).0;
407
408 let (is_short, slice, pad) = if let Some(rem) = 54usize.checked_sub(bytes.len()) {
409 (true, &bytes[27..], 10u128.pow(rem as u32))
410 } else {
411 (false, &bytes[27..54], 1)
412 };
413 let lo = dec_str_int_to_bin::<u128>(slice).0 * pad;
414 ((hi, lo), is_short)
415 }
416 }
417}
418
419fn dec_str_frac_to_bin<I>(bytes: &[u8], nbits: u32) -> Option<I>
420where
421 I: IntHelper<IsSigned = False> + FromStr + From<u8> + DecToBin,
422 I: Mul10 + Shl<u32, Output = I> + Shr<u32, Output = I> + Add<Output = I> + Mul<Output = I>,
423{
424 let (val, is_short) = I::parse_is_short(bytes);
425 let one = I::from(1);
426 let dump_bits = I::NBITS - nbits;
427 let round = if is_short {
429 Round::Nearest
430 } else {
431 Round::Floor
432 };
433 let floor = I::dec_to_bin(val, nbits, round)?;
434 if is_short {
435 return Some(floor);
436 }
437 let (mut boundary, mut add_5) = if nbits == 0 {
441 (I::MSB, false)
442 } else if dump_bits == 0 {
443 (floor, true)
444 } else {
445 ((floor << dump_bits) + (one << (dump_bits - 1)), false)
446 };
447 let mut tie = true;
448 for &byte in bytes {
449 if !add_5 && boundary == I::ZERO {
450 tie = false;
452 break;
453 }
454 let mut boundary_digit = boundary.mul10_assign();
455 if add_5 {
456 let (wrapped, overflow) = boundary.overflowing_add(I::from(5));
457 boundary = wrapped;
458 if overflow {
459 boundary_digit += 1;
460 }
461 add_5 = false;
462 }
463 if byte - b'0' < boundary_digit {
464 return Some(floor);
465 }
466 if byte - b'0' > boundary_digit {
467 tie = false;
468 break;
469 }
470 }
471 if tie && !floor.is_odd() {
472 return Some(floor);
473 }
474 let next_up = floor.checked_add(one)?;
475 if dump_bits != 0 && next_up >> nbits != I::ZERO {
476 None
477 } else {
478 Some(next_up)
479 }
480}
481
482fn mul_hi_lo(lhs: u128, rhs: u128) -> (u128, u128) {
483 const LO: u128 = !(!0 << 64);
484 let (lhs_hi, lhs_lo) = (lhs >> 64, lhs & LO);
485 let (rhs_hi, rhs_lo) = (rhs >> 64, rhs & LO);
486 let lhs_lo_rhs_lo = lhs_lo.wrapping_mul(rhs_lo);
487 let lhs_hi_rhs_lo = lhs_hi.wrapping_mul(rhs_lo);
488 let lhs_lo_rhs_hi = lhs_lo.wrapping_mul(rhs_hi);
489 let lhs_hi_rhs_hi = lhs_hi.wrapping_mul(rhs_hi);
490
491 let col01 = lhs_lo_rhs_lo;
492 let (col01_hi, col01_lo) = (col01 >> 64, col01 & LO);
493 let partial_col12 = lhs_hi_rhs_lo + col01_hi;
494 let (col12, carry_col3) = partial_col12.overflowing_add(lhs_lo_rhs_hi);
495 let (col12_hi, col12_lo) = (col12 >> 64, col12 & LO);
496 let ans01 = (col12_lo << 64) + col01_lo;
497 let ans23 = lhs_hi_rhs_hi + col12_hi + if carry_col3 { 1u128 << 64 } else { 0 };
498 (ans23, ans01)
499}
500fn div_tie(dividend_hi: u128, dividend_lo: u128, divisor: u128) -> (u128, bool) {
501 let ((_, lo), rem) = divisor.div_rem_from((dividend_hi, dividend_lo));
502 (lo, rem == 0)
503}
504
505#[derive(Clone, Copy, Debug, PartialEq, Eq, scale_info::TypeInfo)]
506struct Parse<'a> {
507 neg: bool,
508 int: &'a [u8],
509 frac: &'a [u8],
510}
511
512#[derive(Clone, Copy, Debug, PartialEq, Eq, scale_info::TypeInfo)]
529pub struct ParseFixedError {
530 kind: ParseErrorKind,
531}
532
533#[derive(Clone, Copy, Debug, PartialEq, Eq, scale_info::TypeInfo)]
534enum ParseErrorKind {
535 InvalidDigit,
536 NoDigits,
537 TooManyPoints,
538 Overflow,
539}
540
541impl From<ParseErrorKind> for ParseFixedError {
542 #[inline]
543 fn from(kind: ParseErrorKind) -> ParseFixedError {
544 ParseFixedError { kind }
545 }
546}
547
548impl ParseFixedError {
549 fn message(&self) -> &str {
550 use self::ParseErrorKind::*;
551 match self.kind {
552 InvalidDigit => "invalid digit found in string",
553 NoDigits => "string has no digits",
554 TooManyPoints => "more than one decimal point found in string",
555 Overflow => "overflow",
556 }
557 }
558}
559
560impl Display for ParseFixedError {
561 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
562 Display::fmt(self.message(), f)
563 }
564}
565
566#[cfg(feature = "std")]
567impl Error for ParseFixedError {
568 fn description(&self) -> &str {
569 self.message()
570 }
571}
572
573fn parse_bounds(bytes: &[u8], radix: u32) -> Result<Parse<'_>, ParseFixedError> {
575 let mut sign: Option<bool> = None;
576 let mut trimmed_int_start: Option<usize> = None;
577 let mut point: Option<usize> = None;
578 let mut trimmed_frac_end: Option<usize> = None;
579 let mut has_any_digit = false;
580
581 for (index, &byte) in bytes.iter().enumerate() {
582 match (byte, radix) {
583 (b'+', _) => {
584 if sign.is_some() || point.is_some() || has_any_digit {
585 return Err(ParseErrorKind::InvalidDigit.into());
586 }
587 sign = Some(false);
588 continue;
589 }
590 (b'-', _) => {
591 if sign.is_some() || point.is_some() || has_any_digit {
592 return Err(ParseErrorKind::InvalidDigit.into());
593 }
594 sign = Some(true);
595 continue;
596 }
597 (b'.', _) => {
598 if point.is_some() {
599 return Err(ParseErrorKind::TooManyPoints.into());
600 }
601 point = Some(index);
602 trimmed_frac_end = Some(index + 1);
603 continue;
604 }
605 (b'0'..=b'1', 2)
606 | (b'0'..=b'7', 8)
607 | (b'0'..=b'9', 10)
608 | (b'0'..=b'9', 16)
609 | (b'a'..=b'f', 16)
610 | (b'A'..=b'F', 16) => {
611 if trimmed_int_start.is_none() && point.is_none() && byte != b'0' {
612 trimmed_int_start = Some(index);
613 }
614 if trimmed_frac_end.is_some() && byte != b'0' {
615 trimmed_frac_end = Some(index + 1);
616 }
617 has_any_digit = true;
618 }
619 _ => return Err(ParseErrorKind::InvalidDigit.into()),
620 }
621 }
622 if !has_any_digit {
623 return Err(ParseErrorKind::NoDigits.into());
624 }
625 let neg = sign.unwrap_or(false);
626 let int = match (trimmed_int_start, point) {
627 (Some(start), Some(point)) => &bytes[start..point],
628 (Some(start), None) => &bytes[start..],
629 (None, _) => &bytes[..0],
630 };
631 let frac = match (point, trimmed_frac_end) {
632 (Some(point), Some(end)) => &bytes[(point + 1)..end],
633 _ => &bytes[..0],
634 };
635 Ok(Parse { neg, int, frac })
636}
637
638fn frac_is_half(bytes: &[u8], radix: u32) -> bool {
639 bytes.len() == 1 && bytes[0] - b'0' == (radix as u8) / 2
641}
642
643pub(crate) trait FromStrRadix: Sized {
644 type Err;
645 fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err>;
646 fn saturating_from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err>;
647 fn wrapping_from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err>;
648 fn overflowing_from_str_radix(s: &str, radix: u32) -> Result<(Self, bool), Self::Err>;
649}
650
651macro_rules! impl_from_str_traits {
652 ($Fixed:ident($Bits:ident), $LeEqU:ident; fn $from:ident) => {
653 impl<Frac: $LeEqU> FromStr for $Fixed<Frac> {
654 type Err = ParseFixedError;
655 #[inline]
659 fn from_str(s: &str) -> Result<Self, Self::Err> {
660 Self::from_str_radix(s, 10)
661 }
662 }
663 impl<Frac: $LeEqU> FromStrRadix for $Fixed<Frac> {
664 type Err = ParseFixedError;
665 #[inline]
666 fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err> {
667 match Self::overflowing_from_str_radix(s, radix) {
668 Ok((val, false)) => Ok(val),
669 Ok((_, true)) => Err(ParseErrorKind::Overflow.into()),
670 Err(e) => Err(e),
671 }
672 }
673 #[inline]
674 fn saturating_from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err> {
675 match Self::overflowing_from_str_radix(s, radix) {
676 Ok((val, false)) => Ok(val),
677 Ok((_, true)) => {
678 if s.starts_with('-') {
679 Ok(Self::min_value())
680 } else {
681 Ok(Self::max_value())
682 }
683 }
684 Err(e) => Err(e),
685 }
686 }
687 #[inline]
688 fn wrapping_from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err> {
689 Self::overflowing_from_str_radix(s, radix).map(|(val, _)| val)
690 }
691 #[inline]
692 fn overflowing_from_str_radix(s: &str, radix: u32) -> Result<(Self, bool), Self::Err> {
693 $from(s.as_bytes(), radix, Self::INT_NBITS, Self::FRAC_NBITS)
694 .map(|(bits, overflow)| (Self::from_bits(bits), overflow))
695 }
696 }
697 };
698}
699
700macro_rules! impl_from_str {
701 (
702 $FixedI:ident($BitsI:ident), $FixedU:ident($BitsU:ident), $LeEqU:ident;
703 fn $from_i:ident;
704 fn $from_u:ident;
705 fn $get_int_frac:ident;
706 fn $get_int:ident, ($get_int_half:ident, $attempt_int_half:expr);
707 fn $get_frac:ident, ($get_frac_half:ident, $attempt_frac_half:expr);
708 ) => {
709 impl_from_str_traits! { $FixedI($BitsI), $LeEqU; fn $from_i }
710 impl_from_str_traits! { $FixedU($BitsU), $LeEqU; fn $from_u }
711
712 fn $from_i(
713 bytes: &[u8],
714 radix: u32,
715 int_nbits: u32,
716 frac_nbits: u32,
717 ) -> Result<($BitsI, bool), ParseFixedError> {
718 let (neg, abs, mut overflow) = $get_int_frac(bytes, radix, int_nbits, frac_nbits)?;
719 let max_abs = $BitsU::MSB - if !neg { 1 } else { 0 };
720 if abs > max_abs {
721 overflow = true;
722 }
723 let abs = if neg { abs.wrapping_neg() } else { abs } as $BitsI;
724 Ok((abs, overflow))
725 }
726
727 fn $from_u(
728 bytes: &[u8],
729 radix: u32,
730 int_nbits: u32,
731 frac_nbits: u32,
732 ) -> Result<($BitsU, bool), ParseFixedError> {
733 let (neg, abs, mut overflow) = $get_int_frac(bytes, radix, int_nbits, frac_nbits)?;
734 if neg && abs > 0 {
735 overflow = true;
736 }
737 let abs = if neg { abs.wrapping_neg() } else { abs };
738 Ok((abs, overflow))
739 }
740
741 fn $get_int_frac(
742 bytes: &[u8],
743 radix: u32,
744 int_nbits: u32,
745 frac_nbits: u32,
746 ) -> Result<(bool, $BitsU, bool), ParseFixedError> {
747 let Parse { neg, int, frac } = parse_bounds(bytes, radix)?;
748 let (int_val, mut overflow) = $get_int(int, radix, int_nbits);
749 let (frac_val, frac_overflow) = match $get_frac(frac, radix, frac_nbits) {
750 Some(val) => (val, false),
751 None => (0, true),
752 };
753 let mut val = int_val | frac_val;
754 if frac_overflow || (int_val.is_odd() && frac_nbits == 0 && frac_is_half(frac, radix)) {
761 let (new_val, new_overflow) = if int_nbits == 0 {
762 (val, true)
763 } else {
764 val.overflowing_add(1 << frac_nbits)
765 };
766 if new_overflow {
767 overflow = true;
768 }
769 val = new_val;
770 }
771 Ok((neg, val, overflow))
772 }
773
774 fn $get_int(int: &[u8], radix: u32, nbits: u32) -> ($BitsU, bool) {
775 const HALF: u32 = <$BitsU as IntHelper>::NBITS / 2;
776 if $attempt_int_half && nbits <= HALF {
777 let (half, overflow) = $get_int_half(int, radix, nbits);
778 return ($BitsU::from(half) << HALF, overflow);
779 }
780
781 if int.is_empty() {
782 return (0, false);
783 }
784 let (mut parsed_int, mut overflow): ($BitsU, bool) = match radix {
785 2 => bin_str_int_to_bin(int),
786 8 => oct_str_int_to_bin(int),
787 16 => hex_str_int_to_bin(int),
788 _ => dec_str_int_to_bin(int),
789 };
790 let remove_bits = <$BitsU as IntHelper>::NBITS - nbits;
791 if nbits == 0 {
792 overflow = true;
793 parsed_int = 0;
794 } else if remove_bits > 0 {
795 if (parsed_int >> nbits) != 0 {
796 overflow = true;
797 }
798 parsed_int <<= remove_bits;
799 }
800 (parsed_int, overflow)
801 }
802
803 fn $get_frac(frac: &[u8], radix: u32, nbits: u32) -> Option<$BitsU> {
804 if $attempt_frac_half && nbits <= <$BitsU as IntHelper>::NBITS / 2 {
805 return $get_frac_half(frac, radix, nbits).map($BitsU::from);
806 }
807 if frac.is_empty() {
808 return Some(0);
809 }
810 match radix {
811 2 => bin_str_frac_to_bin(frac, nbits),
812 8 => oct_str_frac_to_bin(frac, nbits),
813 16 => hex_str_frac_to_bin(frac, nbits),
814 10 => dec_str_frac_to_bin(frac, nbits),
815 _ => unreachable!(),
816 }
817 }
818 };
819}
820
821impl_from_str! {
822 FixedI8(i8), FixedU8(u8), LeEqU8;
823 fn from_str_i8;
824 fn from_str_u8;
825 fn get_int_frac8;
826 fn get_int8, (get_int8, false);
827 fn get_frac8, (get_frac8, false);
828}
829impl_from_str! {
830 FixedI16(i16), FixedU16(u16), LeEqU16;
831 fn from_str_i16;
832 fn from_str_u16;
833 fn get_int_frac16;
834 fn get_int16, (get_int8, true);
835 fn get_frac16, (get_frac8, true);
836}
837impl_from_str! {
838 FixedI32(i32), FixedU32(u32), LeEqU32;
839 fn from_str_i32;
840 fn from_str_u32;
841 fn get_int_frac32;
842 fn get_int32, (get_int16, true);
843 fn get_frac32, (get_frac16, true);
844}
845impl_from_str! {
846 FixedI64(i64), FixedU64(u64), LeEqU64;
847 fn from_str_i64;
848 fn from_str_u64;
849 fn get_int_frac64;
850 fn get_int64, (get_int32, true);
851 fn get_frac64, (get_frac32, false);
852}
853impl_from_str! {
854 FixedI128(i128), FixedU128(u128), LeEqU128;
855 fn from_str_i128;
856 fn from_str_u128;
857 fn get_int_frac128;
858 fn get_int128, (get_int64, true);
859 fn get_frac128, (get_frac64, true);
860}
861
862#[cfg(test)]
863mod tests {
864 use crate::{
865 from_str::*,
866 traits::{Fixed, ToFixed},
867 types::*,
868 };
869 use std::{
870 fmt::Debug,
871 format,
872 string::{String, ToString},
873 };
874
875 #[test]
876 fn overflowing() {
877 let overflow = ParseFixedError {
878 kind: ParseErrorKind::Overflow,
879 };
880 assert_eq!(
881 U4F4::overflowing_from_str("15.5"),
882 Ok((U4F4::from_bits(0xF8), false))
883 );
884 assert_eq!(U4F4::from_str("15.5"), Ok(U4F4::from_bits(0xF8)));
885 assert_eq!(
886 U4F4::overflowing_from_str("31.5"),
887 Ok((U4F4::from_bits(0xF8), true))
888 );
889 assert_eq!(U4F4::from_str("31.5"), Err(overflow));
890 assert_eq!(
891 U4F4::overflowing_from_str("271.5"),
892 Ok((U4F4::from_bits(0xF8), true))
893 );
894 assert_eq!(
895 U8F0::overflowing_from_str("271"),
896 Ok((U8F0::from_bits(0x0F), true))
897 );
898 let longer_than_8 = format!("{}", (1 << 30) + 15);
899 assert_eq!(
900 U8F0::overflowing_from_str(&longer_than_8),
901 Ok((U8F0::from_bits(0x0F), true))
902 );
903
904 assert_eq!(
905 U4F4::overflowing_from_str_binary("1111.1000"),
906 Ok((U4F4::from_bits(0xF8), false))
907 );
908 assert_eq!(
909 U4F4::from_str_binary("1111.1000"),
910 Ok(U4F4::from_bits(0xF8))
911 );
912 assert_eq!(
913 U4F4::overflowing_from_str_binary("11111.1000"),
914 Ok((U4F4::from_bits(0xF8), true))
915 );
916 assert_eq!(U4F4::from_str_binary("11111.1000"), Err(overflow));
917 assert_eq!(
918 U8F0::overflowing_from_str_binary("100001111"),
919 Ok((U8F0::from_bits(0x0F), true))
920 );
921
922 assert_eq!(
923 U4F4::overflowing_from_str_octal("17.7"),
924 Ok((U4F4::from_bits(0xFE), false))
925 );
926 assert_eq!(U4F4::from_str_octal("17.7"), Ok(U4F4::from_bits(0xFE)));
927 assert_eq!(
928 U4F4::overflowing_from_str_octal("77.7"),
929 Ok((U4F4::from_bits(0xFE), true))
930 );
931 assert_eq!(U4F4::from_str_octal("77.7"), Err(overflow));
932 assert_eq!(
933 U4F4::overflowing_from_str_octal("707.7"),
934 Ok((U4F4::from_bits(0x7E), true))
935 );
936 assert_eq!(
937 U8F0::overflowing_from_str_octal("1307"),
938 Ok((U8F0::from_bits(0o307), true))
939 );
940
941 assert_eq!(
942 U6F10::overflowing_from_str_hex("3F.8"),
943 Ok((U6F10::from_bits(0xFE00), false))
944 );
945 assert_eq!(U6F10::from_str_hex("3F.8"), Ok(U6F10::from_bits(0xFE00)));
946 assert_eq!(
947 U6F10::overflowing_from_str_hex("FF.8"),
948 Ok((U6F10::from_bits(0xFE00), true))
949 );
950 assert_eq!(U6F10::from_str_hex("FF.8"), Err(overflow));
951 assert_eq!(
952 U6F10::overflowing_from_str_hex("F0F.8"),
953 Ok((U6F10::from_bits(0x3E00), true))
954 );
955 assert_eq!(
956 U16F0::overflowing_from_str_hex("100FF"),
957 Ok((U16F0::from_bits(0x00FF), true))
958 );
959 }
960
961 #[test]
962 fn check_dec_8() {
963 let two_pow = 8f64.exp2();
964 let limit = 1000;
965 for i in 0..limit {
966 let ans = <u8 as DecToBin>::dec_to_bin(i, 8, Round::Nearest);
967 let approx = two_pow * f64::from(i) / f64::from(limit);
968 let error = (ans.map(f64::from).unwrap_or(two_pow) - approx).abs();
969 assert!(
970 error <= 0.5,
971 "i {} ans {:?} approx {} error {}",
972 i,
973 ans,
974 approx,
975 error
976 );
977 }
978 }
979
980 #[test]
981 fn check_dec_16() {
982 let two_pow = 16f64.exp2();
983 let limit = 1_000_000;
984 for i in 0..limit {
985 let ans = <u16 as DecToBin>::dec_to_bin(i, 16, Round::Nearest);
986 let approx = two_pow * f64::from(i) / f64::from(limit);
987 let error = (ans.map(f64::from).unwrap_or(two_pow) - approx).abs();
988 assert!(
989 error <= 0.5,
990 "i {} ans {:?} approx {} error {}",
991 i,
992 ans,
993 approx,
994 error
995 );
996 }
997 }
998
999 #[test]
1000 fn check_dec_32() {
1001 let two_pow = 32f64.exp2();
1002 let limit = 10_000_000_000_000;
1003 for iter in 0..1_000_000 {
1004 for &i in &[
1005 iter,
1006 limit / 4 - 1 - iter,
1007 limit / 4 + iter,
1008 limit / 3 - 1 - iter,
1009 limit / 3 + iter,
1010 limit / 2 - 1 - iter,
1011 limit / 2 + iter,
1012 limit - iter - 1,
1013 ] {
1014 let ans = <u32 as DecToBin>::dec_to_bin(i, 32, Round::Nearest);
1015 let approx = two_pow * i as f64 / limit as f64;
1016 let error = (ans.map(f64::from).unwrap_or(two_pow) - approx).abs();
1017 assert!(
1018 error <= 0.5,
1019 "i {} ans {:?} approx {} error {}",
1020 i,
1021 ans,
1022 approx,
1023 error
1024 );
1025 }
1026 }
1027 }
1028
1029 #[test]
1030 fn check_dec_64() {
1031 let two_pow = 64f64.exp2();
1032 let limit = 1_000_000_000_000_000_000_000_000_000;
1033 for iter in 0..200_000 {
1034 for &i in &[
1035 iter,
1036 limit / 4 - 1 - iter,
1037 limit / 4 + iter,
1038 limit / 3 - 1 - iter,
1039 limit / 3 + iter,
1040 limit / 2 - 1 - iter,
1041 limit / 2 + iter,
1042 limit - iter - 1,
1043 ] {
1044 let ans = <u64 as DecToBin>::dec_to_bin(i, 64, Round::Nearest);
1045 let approx = two_pow * i as f64 / limit as f64;
1046 let error = (ans.map(|x| x as f64).unwrap_or(two_pow) - approx).abs();
1047 assert!(
1048 error <= 0.5,
1049 "i {} ans {:?} approx {} error {}",
1050 i,
1051 ans,
1052 approx,
1053 error
1054 );
1055 }
1056 }
1057 }
1058
1059 #[test]
1060 fn check_dec_128() {
1061 let nines = 10u128.pow(27) - 1;
1062 let zeros = 0;
1063 let too_big = <u128 as DecToBin>::dec_to_bin((nines, nines), 128, Round::Nearest);
1064 assert_eq!(too_big, None);
1065 let big = <u128 as DecToBin>::dec_to_bin((nines, zeros), 128, Round::Nearest);
1066 assert_eq!(
1067 big,
1068 Some(340_282_366_920_938_463_463_374_607_091_485_844_535)
1069 );
1070 let small = <u128 as DecToBin>::dec_to_bin((zeros, nines), 128, Round::Nearest);
1071 assert_eq!(small, Some(340_282_366_921));
1072 let zero = <u128 as DecToBin>::dec_to_bin((zeros, zeros), 128, Round::Nearest);
1073 assert_eq!(zero, Some(0));
1074 let x = <u128 as DecToBin>::dec_to_bin(
1075 (
1076 123_456_789_012_345_678_901_234_567,
1077 987_654_321_098_765_432_109_876_543,
1078 ),
1079 128,
1080 Round::Nearest,
1081 );
1082 assert_eq!(x, Some(42_010_168_377_579_896_403_540_037_811_203_677_112));
1083
1084 let eights = 888_888_888_888_888_888_888_888_888;
1085 let narrow = <u128 as DecToBin>::dec_to_bin((eights, zeros), 40, Round::Nearest);
1086 assert_eq!(narrow, Some(977_343_669_134));
1087 }
1088
1089 #[test]
1090 fn check_parse_bounds() {
1091 let Parse { neg, int, frac } = parse_bounds(b"-12.34", 10).unwrap();
1092 assert_eq!((neg, int, frac), (true, &b"12"[..], &b"34"[..]));
1093 let Parse { neg, int, frac } = parse_bounds(b"012.", 10).unwrap();
1094 assert_eq!((neg, int, frac), (false, &b"12"[..], &b""[..]));
1095 let Parse { neg, int, frac } = parse_bounds(b"+.340", 10).unwrap();
1096 assert_eq!((neg, int, frac), (false, &b""[..], &b"34"[..]));
1097 let Parse { neg, int, frac } = parse_bounds(b"0", 10).unwrap();
1098 assert_eq!((neg, int, frac), (false, &b""[..], &b""[..]));
1099 let Parse { neg, int, frac } = parse_bounds(b"-.C1A0", 16).unwrap();
1100 assert_eq!((neg, int, frac), (true, &b""[..], &b"C1A"[..]));
1101
1102 let ParseFixedError { kind } = parse_bounds(b"0 ", 10).unwrap_err();
1103 assert_eq!(kind, ParseErrorKind::InvalidDigit);
1104 let ParseFixedError { kind } = parse_bounds(b"+-", 10).unwrap_err();
1105 assert_eq!(kind, ParseErrorKind::InvalidDigit);
1106 let ParseFixedError { kind } = parse_bounds(b"+.", 10).unwrap_err();
1107 assert_eq!(kind, ParseErrorKind::NoDigits);
1108 let ParseFixedError { kind } = parse_bounds(b".1.", 10).unwrap_err();
1109 assert_eq!(kind, ParseErrorKind::TooManyPoints);
1110 let ParseFixedError { kind } = parse_bounds(b"1+2", 10).unwrap_err();
1111 assert_eq!(kind, ParseErrorKind::InvalidDigit);
1112 let ParseFixedError { kind } = parse_bounds(b"1-2", 10).unwrap_err();
1113 assert_eq!(kind, ParseErrorKind::InvalidDigit);
1114 }
1115
1116 fn assert_ok<F>(s: &str, radix: u32, bits: F::Bits, overflow: bool)
1117 where
1118 F: Fixed + FromStrRadix<Err = ParseFixedError>,
1119 F::Bits: Eq + Debug,
1120 {
1121 match F::overflowing_from_str_radix(s, radix) {
1122 Ok((f, o)) => {
1123 assert_eq!(f.to_bits(), bits, "{} -> ({}, {})", s, f, o);
1124 assert_eq!(o, overflow, "{} -> ({}, {})", s, f, o);
1125 }
1126 Err(e) => panic!("could not parse {}: {}", s, e),
1127 }
1128 }
1129
1130 #[test]
1131 fn check_i8_u8_from_str() {
1132 assert_ok::<I0F8>("-1", 10, 0x00, true);
1133 assert_ok::<I0F8>("-0.502", 10, 0x7F, true);
1134 assert_ok::<I0F8>("-0.501", 10, -0x80, false);
1135 assert_ok::<I0F8>("0.498", 10, 0x7F, false);
1136 assert_ok::<I0F8>("0.499", 10, -0x80, true);
1137 assert_ok::<I0F8>("1", 10, 0x00, true);
1138
1139 assert_ok::<I4F4>("-8.04", 10, 0x7F, true);
1140 assert_ok::<I4F4>("-8.03", 10, -0x80, false);
1141 assert_ok::<I4F4>("7.96", 10, 0x7F, false);
1142 assert_ok::<I4F4>("7.97", 10, -0x80, true);
1143
1144 assert_ok::<I8F0>("-128.501", 10, 0x7F, true);
1145 assert_ok::<I8F0>("-128.5", 10, -0x80, false);
1147 assert_ok::<I8F0>("127.499", 10, 0x7F, false);
1148 assert_ok::<I8F0>("127.5", 10, -0x80, true);
1150
1151 assert_ok::<U0F8>("-0", 10, 0x00, false);
1152 assert_ok::<U0F8>("0.498", 10, 0x7F, false);
1153 assert_ok::<U0F8>("0.499", 10, 0x80, false);
1154 assert_ok::<U0F8>("0.998", 10, 0xFF, false);
1155 assert_ok::<U0F8>("0.999", 10, 0x00, true);
1156 assert_ok::<U0F8>("1", 10, 0x00, true);
1157
1158 assert_ok::<U4F4>("7.96", 10, 0x7F, false);
1159 assert_ok::<U4F4>("7.97", 10, 0x80, false);
1160 assert_ok::<U4F4>("15.96", 10, 0xFF, false);
1161 assert_ok::<U4F4>("15.97", 10, 0x00, true);
1162
1163 assert_ok::<U8F0>("127.499", 10, 0x7F, false);
1164 assert_ok::<U8F0>("127.5", 10, 0x80, false);
1166 assert_ok::<U8F0>("255.499", 10, 0xFF, false);
1167 assert_ok::<U8F0>("255.5", 10, 0x00, true);
1169 }
1170
1171 #[test]
1172 fn check_i16_u16_from_str() {
1173 assert_ok::<I0F16>("-1", 10, 0x00, true);
1174 assert_ok::<I0F16>("-0.500008", 10, 0x7FFF, true);
1175 assert_ok::<I0F16>("-0.500007", 10, -0x8000, false);
1176 assert_ok::<I0F16>("+0.499992", 10, 0x7FFF, false);
1177 assert_ok::<I0F16>("+0.499993", 10, -0x8000, true);
1178 assert_ok::<I0F16>("1", 10, 0x0000, true);
1179
1180 assert_ok::<I8F8>("-128.002", 10, 0x7FFF, true);
1181 assert_ok::<I8F8>("-128.001", 10, -0x8000, false);
1182 assert_ok::<I8F8>("+127.998", 10, 0x7FFF, false);
1183 assert_ok::<I8F8>("+127.999", 10, -0x8000, true);
1184
1185 assert_ok::<I16F0>("-32768.500001", 10, 0x7FFF, true);
1186 assert_ok::<I16F0>("-32768.5", 10, -0x8000, false);
1188 assert_ok::<I16F0>("+32767.499999", 10, 0x7FFF, false);
1189 assert_ok::<I16F0>("+32767.5", 10, -0x8000, true);
1191
1192 assert_ok::<U0F16>("-0", 10, 0x0000, false);
1193 assert_ok::<U0F16>("0.499992", 10, 0x7FFF, false);
1194 assert_ok::<U0F16>("0.499993", 10, 0x8000, false);
1195 assert_ok::<U0F16>("0.999992", 10, 0xFFFF, false);
1196 assert_ok::<U0F16>("0.999993", 10, 0x0000, true);
1197 assert_ok::<U0F16>("1", 10, 0x0000, true);
1198
1199 assert_ok::<U8F8>("127.998", 10, 0x7FFF, false);
1200 assert_ok::<U8F8>("127.999", 10, 0x8000, false);
1201 assert_ok::<U8F8>("255.998", 10, 0xFFFF, false);
1202 assert_ok::<U8F8>("255.999", 10, 0x0000, true);
1203
1204 assert_ok::<U16F0>("32767.499999", 10, 0x7FFF, false);
1205 assert_ok::<U16F0>("32767.5", 10, 0x8000, false);
1207 assert_ok::<U16F0>("65535.499999", 10, 0xFFFF, false);
1208 assert_ok::<U16F0>("65535.5", 10, 0x0000, true);
1210 }
1211
1212 #[test]
1213 fn check_i32_u32_from_str() {
1214 assert_ok::<I0F32>("-1", 10, 0x0000_0000, true);
1215 assert_ok::<I0F32>("-0.5000000002", 10, 0x7FFF_FFFF, true);
1216 assert_ok::<I0F32>("-0.5000000001", 10, -0x8000_0000, false);
1217 assert_ok::<I0F32>("0.4999999998", 10, 0x7FFF_FFFF, false);
1218 assert_ok::<I0F32>("0.4999999999", 10, -0x8000_0000, true);
1219 assert_ok::<I0F32>("1", 10, 0x0000_0000, true);
1220
1221 assert_ok::<I16F16>("-32768.000008", 10, 0x7FFF_FFFF, true);
1222 assert_ok::<I16F16>("-32768.000007", 10, -0x8000_0000, false);
1223 assert_ok::<I16F16>("32767.999992", 10, 0x7FFF_FFFF, false);
1224 assert_ok::<I16F16>("32767.999993", 10, -0x8000_0000, true);
1225
1226 assert_ok::<I32F0>("-2147483648.5000000001", 10, 0x7FFF_FFFF, true);
1227 assert_ok::<I32F0>("-2147483648.5", 10, -0x8000_0000, false);
1229 assert_ok::<I32F0>("2147483647.4999999999", 10, 0x7FFF_FFFF, false);
1230 assert_ok::<I32F0>("2147483647.5", 10, -0x8000_0000, true);
1232
1233 assert_ok::<U0F32>("-0", 10, 0x0000_0000, false);
1234 assert_ok::<U0F32>("0.4999999998", 10, 0x7FFF_FFFF, false);
1235 assert_ok::<U0F32>("0.4999999999", 10, 0x8000_0000, false);
1236 assert_ok::<U0F32>("0.9999999998", 10, 0xFFFF_FFFF, false);
1237 assert_ok::<U0F32>("0.9999999999", 10, 0x0000_0000, true);
1238 assert_ok::<U0F32>("1", 10, 0x0000_0000, true);
1239
1240 assert_ok::<U16F16>("32767.999992", 10, 0x7FFF_FFFF, false);
1241 assert_ok::<U16F16>("32767.999993", 10, 0x8000_0000, false);
1242 assert_ok::<U16F16>("65535.999992", 10, 0xFFFF_FFFF, false);
1243 assert_ok::<U16F16>("65535.999993", 10, 0x0000_0000, true);
1244
1245 assert_ok::<U32F0>("2147483647.4999999999", 10, 0x7FFF_FFFF, false);
1246 assert_ok::<U32F0>("2147483647.5", 10, 0x8000_0000, false);
1248 assert_ok::<U32F0>("4294967295.4999999999", 10, 0xFFFF_FFFF, false);
1249 assert_ok::<U32F0>("4294967295.5", 10, 0x0000_0000, true);
1251 }
1252
1253 #[test]
1254 fn check_i64_u64_from_str() {
1255 assert_ok::<I0F64>("-1", 10, 0x0000_0000_0000_0000, true);
1256 assert_ok::<I0F64>("-0.50000000000000000003", 10, 0x7FFF_FFFF_FFFF_FFFF, true);
1257 assert_ok::<I0F64>("-0.50000000000000000002", 10, -0x8000_0000_0000_0000, false);
1258 assert_ok::<I0F64>("+0.49999999999999999997", 10, 0x7FFF_FFFF_FFFF_FFFF, false);
1259 assert_ok::<I0F64>("+0.49999999999999999998", 10, -0x8000_0000_0000_0000, true);
1260 assert_ok::<I0F64>("1", 10, 0x0000_0000_0000_0000, true);
1261
1262 assert_ok::<I32F32>("-2147483648.0000000002", 10, 0x7FFF_FFFF_FFFF_FFFF, true);
1263 assert_ok::<I32F32>("-2147483648.0000000001", 10, -0x8000_0000_0000_0000, false);
1264 assert_ok::<I32F32>("2147483647.9999999998", 10, 0x7FFF_FFFF_FFFF_FFFF, false);
1265 assert_ok::<I32F32>("2147483647.9999999999", 10, -0x8000_0000_0000_0000, true);
1266
1267 assert_ok::<I64F0>(
1268 "-9223372036854775808.50000000000000000001",
1269 10,
1270 0x7FFF_FFFF_FFFF_FFFF,
1271 true,
1272 );
1273 assert_ok::<I64F0>("-9223372036854775808.5", 10, -0x8000_0000_0000_0000, false);
1275 assert_ok::<I64F0>(
1276 "9223372036854775807.49999999999999999999",
1277 10,
1278 0x7FFF_FFFF_FFFF_FFFF,
1279 false,
1280 );
1281 assert_ok::<I64F0>("9223372036854775807.5", 10, -0x8000_0000_0000_0000, true);
1283
1284 assert_ok::<U0F64>("-0", 10, 0x0000_0000_0000_0000, false);
1285 assert_ok::<U0F64>("0.49999999999999999997", 10, 0x7FFF_FFFF_FFFF_FFFF, false);
1286 assert_ok::<U0F64>("0.49999999999999999998", 10, 0x8000_0000_0000_0000, false);
1287 assert_ok::<U0F64>("0.99999999999999999997", 10, 0xFFFF_FFFF_FFFF_FFFF, false);
1288 assert_ok::<U0F64>("0.99999999999999999998", 10, 0x0000_0000_0000_0000, true);
1289 assert_ok::<U0F64>("1", 10, 0x0000_0000_0000_0000, true);
1290
1291 assert_ok::<U32F32>("2147483647.9999999998", 10, 0x7FFF_FFFF_FFFF_FFFF, false);
1292 assert_ok::<U32F32>("2147483647.9999999999", 10, 0x8000_0000_0000_0000, false);
1293 assert_ok::<U32F32>("4294967295.9999999998", 10, 0xFFFF_FFFF_FFFF_FFFF, false);
1294 assert_ok::<U32F32>("4294967295.9999999999", 10, 0x0000_0000_0000_0000, true);
1295
1296 assert_ok::<U64F0>(
1297 "9223372036854775807.49999999999999999999",
1298 10,
1299 0x7FFF_FFFF_FFFF_FFFF,
1300 false,
1301 );
1302 assert_ok::<U64F0>("9223372036854775807.5", 10, 0x8000_0000_0000_0000, false);
1304 assert_ok::<U64F0>(
1305 "18446744073709551615.49999999999999999999",
1306 10,
1307 0xFFFF_FFFF_FFFF_FFFF,
1308 false,
1309 );
1310 assert_ok::<U64F0>("18446744073709551615.5", 10, 0x0000_0000_0000_0000, true);
1312 }
1313
1314 #[test]
1315 fn check_i128_u128_from_str() {
1316 assert_ok::<I0F128>("-1", 10, 0x0000_0000_0000_0000_0000_0000_0000_0000, true);
1317 assert_ok::<I0F128>(
1318 "-0.500000000000000000000000000000000000002",
1319 10,
1320 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1321 true,
1322 );
1323 assert_ok::<I0F128>(
1324 "-0.500000000000000000000000000000000000001",
1325 10,
1326 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1327 false,
1328 );
1329 assert_ok::<I0F128>(
1330 "0.499999999999999999999999999999999999998",
1331 10,
1332 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1333 false,
1334 );
1335 assert_ok::<I0F128>(
1336 "0.499999999999999999999999999999999999999",
1337 10,
1338 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1339 true,
1340 );
1341 assert_ok::<I0F128>("1", 10, 0x0000_0000_0000_0000_0000_0000_0000_0000, true);
1342
1343 assert_ok::<I64F64>(
1344 "-9223372036854775808.00000000000000000003",
1345 10,
1346 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1347 true,
1348 );
1349 assert_ok::<I64F64>(
1350 "-9223372036854775808.00000000000000000002",
1351 10,
1352 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1353 false,
1354 );
1355 assert_ok::<I64F64>(
1356 "9223372036854775807.99999999999999999997",
1357 10,
1358 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1359 false,
1360 );
1361 assert_ok::<I64F64>(
1362 "9223372036854775807.99999999999999999998",
1363 10,
1364 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1365 true,
1366 );
1367
1368 assert_ok::<I128F0>(
1369 "-170141183460469231731687303715884105728.5000000000000000000000000000000000000001",
1370 10,
1371 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1372 true,
1373 );
1374 assert_ok::<I128F0>(
1376 "-170141183460469231731687303715884105728.5",
1377 10,
1378 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1379 false,
1380 );
1381 assert_ok::<I128F0>(
1382 "170141183460469231731687303715884105727.4999999999999999999999999999999999999999",
1383 10,
1384 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1385 false,
1386 );
1387 assert_ok::<I128F0>(
1389 "170141183460469231731687303715884105727.5",
1390 10,
1391 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1392 true,
1393 );
1394
1395 assert_ok::<U0F128>("-0", 10, 0x0000_0000_0000_0000_0000_0000_0000_0000, false);
1396 assert_ok::<U0F128>(
1397 "0.499999999999999999999999999999999999998",
1398 10,
1399 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1400 false,
1401 );
1402 assert_ok::<U0F128>(
1403 "0.499999999999999999999999999999999999999",
1404 10,
1405 0x8000_0000_0000_0000_0000_0000_0000_0000,
1406 false,
1407 );
1408 assert_ok::<U0F128>(
1409 "0.999999999999999999999999999999999999998",
1410 10,
1411 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1412 false,
1413 );
1414 assert_ok::<U0F128>(
1415 "0.999999999999999999999999999999999999999",
1416 10,
1417 0x0000_0000_0000_0000_0000_0000_0000_0000,
1418 true,
1419 );
1420 assert_ok::<U0F128>("1", 10, 0x0000_0000_0000_0000_0000_0000_0000_0000, true);
1421
1422 assert_ok::<U64F64>(
1423 "9223372036854775807.99999999999999999997",
1424 10,
1425 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1426 false,
1427 );
1428 assert_ok::<U64F64>(
1429 "9223372036854775807.99999999999999999998",
1430 10,
1431 0x8000_0000_0000_0000_0000_0000_0000_0000,
1432 false,
1433 );
1434 assert_ok::<U64F64>(
1435 "18446744073709551615.99999999999999999997",
1436 10,
1437 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1438 false,
1439 );
1440 assert_ok::<U64F64>(
1441 "18446744073709551615.99999999999999999998",
1442 10,
1443 0x0000_0000_0000_0000_0000_0000_0000_0000,
1444 true,
1445 );
1446
1447 assert_ok::<U128F0>(
1448 "170141183460469231731687303715884105727.4999999999999999999999999999999999999999",
1449 10,
1450 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1451 false,
1452 );
1453 assert_ok::<U128F0>(
1455 "170141183460469231731687303715884105727.5",
1456 10,
1457 0x8000_0000_0000_0000_0000_0000_0000_0000,
1458 false,
1459 );
1460 assert_ok::<U128F0>(
1461 "340282366920938463463374607431768211455.4999999999999999999999999999999999999999",
1462 10,
1463 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1464 false,
1465 );
1466 assert_ok::<U128F0>(
1468 "340282366920938463463374607431768211455.5",
1469 10,
1470 0x0000_0000_0000_0000_0000_0000_0000_0000,
1471 true,
1472 );
1473 }
1474
1475 #[test]
1476 fn check_i16_u16_from_str_binary() {
1477 assert_ok::<I0F16>("-1", 2, 0x0000, true);
1478 assert_ok::<I0F16>("-0.100000000000000011", 2, 0x7FFF, true);
1479 assert_ok::<I0F16>("-0.100000000000000010", 2, -0x8000, false);
1480 assert_ok::<I0F16>("-0.011111111111111110", 2, -0x8000, false);
1481 assert_ok::<I0F16>("+0.011111111111111101", 2, 0x7FFF, false);
1482 assert_ok::<I0F16>("+0.011111111111111110", 2, -0x8000, true);
1483 assert_ok::<I0F16>("1", 2, 0x0000, true);
1484
1485 assert_ok::<I8F8>("-10000000.0000000011", 2, 0x7FFF, true);
1486 assert_ok::<I8F8>("-10000000.0000000010", 2, -0x8000, false);
1487 assert_ok::<I8F8>("-01111111.1111111110", 2, -0x8000, false);
1488 assert_ok::<I8F8>("+01111111.1111111101", 2, 0x7FFF, false);
1489 assert_ok::<I8F8>("+01111111.1111111110", 2, -0x8000, true);
1490
1491 assert_ok::<I16F0>("-1000000000000000.11", 2, 0x7FFF, true);
1492 assert_ok::<I16F0>("-1000000000000000.10", 2, -0x8000, false);
1493 assert_ok::<I16F0>("-0111111111111111.10", 2, -0x8000, false);
1494 assert_ok::<I16F0>("+0111111111111111.01", 2, 0x7FFF, false);
1495 assert_ok::<I16F0>("+0111111111111111.10", 2, -0x8000, true);
1496
1497 assert_ok::<U0F16>("-0", 2, 0x0000, false);
1498 assert_ok::<U0F16>("0.011111111111111101", 2, 0x7FFF, false);
1499 assert_ok::<U0F16>("0.011111111111111110", 2, 0x8000, false);
1500 assert_ok::<U0F16>("0.111111111111111101", 2, 0xFFFF, false);
1501 assert_ok::<U0F16>("0.111111111111111110", 2, 0x0000, true);
1502 assert_ok::<U0F16>("1", 2, 0x0000, true);
1503
1504 assert_ok::<U8F8>("01111111.1111111101", 2, 0x7FFF, false);
1505 assert_ok::<U8F8>("01111111.1111111110", 2, 0x8000, false);
1506 assert_ok::<U8F8>("11111111.1111111101", 2, 0xFFFF, false);
1507 assert_ok::<U8F8>("11111111.1111111110", 2, 0x0000, true);
1508
1509 assert_ok::<U16F0>("0111111111111111.01", 2, 0x7FFF, false);
1510 assert_ok::<U16F0>("0111111111111111.10", 2, 0x8000, false);
1511 assert_ok::<U16F0>("1111111111111111.01", 2, 0xFFFF, false);
1512 assert_ok::<U16F0>("1111111111111111.10", 2, 0x0000, true);
1513 }
1514
1515 #[test]
1516 fn check_i16_u16_from_str_octal() {
1517 assert_ok::<I0F16>("-1", 8, 0x0000, true);
1518 assert_ok::<I0F16>("-0.400003", 8, 0x7FFF, true);
1519 assert_ok::<I0F16>("-0.400002", 8, -0x8000, false);
1520 assert_ok::<I0F16>("-0.377776", 8, -0x8000, false);
1521 assert_ok::<I0F16>("+0.377775", 8, 0x7FFF, false);
1522 assert_ok::<I0F16>("+0.377776", 8, -0x8000, true);
1523 assert_ok::<I0F16>("1", 8, 0x0000, true);
1524
1525 assert_ok::<I8F8>("-200.0011", 8, 0x7FFF, true);
1526 assert_ok::<I8F8>("-200.0010", 8, -0x8000, false);
1527 assert_ok::<I8F8>("-177.7770", 8, -0x8000, false);
1528 assert_ok::<I8F8>("+177.7767", 8, 0x7FFF, false);
1529 assert_ok::<I8F8>("+177.7770", 8, -0x8000, true);
1530
1531 assert_ok::<I16F0>("-100000.5", 8, 0x7FFF, true);
1532 assert_ok::<I16F0>("-100000.4", 8, -0x8000, false);
1533 assert_ok::<I16F0>("-077777.4", 8, -0x8000, false);
1534 assert_ok::<I16F0>("+077777.3", 8, 0x7FFF, false);
1535 assert_ok::<I16F0>("+077777.4", 8, -0x8000, true);
1536
1537 assert_ok::<U0F16>("-0", 8, 0x0000, false);
1538 assert_ok::<U0F16>("0.377775", 8, 0x7FFF, false);
1539 assert_ok::<U0F16>("0.377776", 8, 0x8000, false);
1540 assert_ok::<U0F16>("0.777775", 8, 0xFFFF, false);
1541 assert_ok::<U0F16>("0.777776", 8, 0x0000, true);
1542 assert_ok::<U0F16>("1", 8, 0x0000, true);
1543
1544 assert_ok::<U8F8>("177.7767", 8, 0x7FFF, false);
1545 assert_ok::<U8F8>("177.7770", 8, 0x8000, false);
1546 assert_ok::<U8F8>("377.7767", 8, 0xFFFF, false);
1547 assert_ok::<U8F8>("377.7770", 8, 0x0000, true);
1548
1549 assert_ok::<U16F0>("077777.3", 8, 0x7FFF, false);
1550 assert_ok::<U16F0>("077777.4", 8, 0x8000, false);
1551 assert_ok::<U16F0>("177777.3", 8, 0xFFFF, false);
1552 assert_ok::<U16F0>("177777.4", 8, 0x0000, true);
1553 }
1554
1555 #[test]
1556 fn check_i16_u16_from_str_hex() {
1557 assert_ok::<I0F16>("-1", 16, 0x0000, true);
1558 assert_ok::<I0F16>("-0.80009", 16, 0x7FFF, true);
1559 assert_ok::<I0F16>("-0.80008", 16, -0x8000, false);
1560 assert_ok::<I0F16>("-0.7FFF8", 16, -0x8000, false);
1561 assert_ok::<I0F16>("+0.7FFF7", 16, 0x7FFF, false);
1562 assert_ok::<I0F16>("+0.7FFF8", 16, -0x8000, true);
1563 assert_ok::<I0F16>("1", 16, 0x0000, true);
1564
1565 assert_ok::<I8F8>("-80.009", 16, 0x7FFF, true);
1566 assert_ok::<I8F8>("-80.008", 16, -0x8000, false);
1567 assert_ok::<I8F8>("-7F.FF8", 16, -0x8000, false);
1568 assert_ok::<I8F8>("+7F.FF7", 16, 0x7FFF, false);
1569 assert_ok::<I8F8>("+7F.FF8", 16, -0x8000, true);
1570
1571 assert_ok::<I16F0>("-8000.9", 16, 0x7FFF, true);
1572 assert_ok::<I16F0>("-8000.8", 16, -0x8000, false);
1573 assert_ok::<I16F0>("-7FFF.8", 16, -0x8000, false);
1574 assert_ok::<I16F0>("+7FFF.7", 16, 0x7FFF, false);
1575 assert_ok::<I16F0>("+7FFF.8", 16, -0x8000, true);
1576
1577 assert_ok::<U0F16>("-0", 16, 0x0000, false);
1578 assert_ok::<U0F16>("0.7FFF7", 16, 0x7FFF, false);
1579 assert_ok::<U0F16>("0.7FFF8", 16, 0x8000, false);
1580 assert_ok::<U0F16>("0.FFFF7", 16, 0xFFFF, false);
1581 assert_ok::<U0F16>("0.FFFF8", 16, 0x0000, true);
1582 assert_ok::<U0F16>("1", 16, 0x0000, true);
1583
1584 assert_ok::<U8F8>("7F.FF7", 16, 0x7FFF, false);
1585 assert_ok::<U8F8>("7F.FF8", 16, 0x8000, false);
1586 assert_ok::<U8F8>("FF.FF7", 16, 0xFFFF, false);
1587 assert_ok::<U8F8>("FF.FF8", 16, 0x0000, true);
1588
1589 assert_ok::<U16F0>("7FFF.7", 16, 0x7FFF, false);
1590 assert_ok::<U16F0>("7FFF.8", 16, 0x8000, false);
1591 assert_ok::<U16F0>("FFFF.7", 16, 0xFFFF, false);
1592 assert_ok::<U16F0>("FFFF.8", 16, 0x0000, true);
1593 }
1594
1595 #[test]
1596 fn check_i128_u128_from_str_hex() {
1597 assert_ok::<I0F128>("-1", 16, 0x0000_0000_0000_0000_0000_0000_0000_0000, true);
1598 assert_ok::<I0F128>(
1599 "-0.800000000000000000000000000000009",
1600 16,
1601 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1602 true,
1603 );
1604 assert_ok::<I0F128>(
1605 "-0.800000000000000000000000000000008",
1606 16,
1607 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1608 false,
1609 );
1610 assert_ok::<I0F128>(
1611 "-0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
1612 16,
1613 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1614 false,
1615 );
1616 assert_ok::<I0F128>(
1617 "+0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7",
1618 16,
1619 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1620 false,
1621 );
1622 assert_ok::<I0F128>(
1623 "+0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
1624 16,
1625 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1626 true,
1627 );
1628 assert_ok::<I0F128>("1", 16, 0x0000_0000_0000_0000_0000_0000_0000_0000, true);
1629
1630 assert_ok::<I64F64>(
1631 "-8000000000000000.00000000000000009",
1632 16,
1633 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1634 true,
1635 );
1636 assert_ok::<I64F64>(
1637 "-8000000000000000.00000000000000008",
1638 16,
1639 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1640 false,
1641 );
1642 assert_ok::<I64F64>(
1643 "-7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8",
1644 16,
1645 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1646 false,
1647 );
1648 assert_ok::<I64F64>(
1649 "+7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF7",
1650 16,
1651 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1652 false,
1653 );
1654 assert_ok::<I64F64>(
1655 "+7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8",
1656 16,
1657 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1658 true,
1659 );
1660
1661 assert_ok::<I128F0>(
1662 "-80000000000000000000000000000000.9",
1663 16,
1664 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1665 true,
1666 );
1667 assert_ok::<I128F0>(
1668 "-80000000000000000000000000000000.8",
1669 16,
1670 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1671 false,
1672 );
1673 assert_ok::<I128F0>(
1674 "-7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8",
1675 16,
1676 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1677 false,
1678 );
1679 assert_ok::<I128F0>(
1680 "+7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.7",
1681 16,
1682 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1683 false,
1684 );
1685 assert_ok::<I128F0>(
1686 "+7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8",
1687 16,
1688 -0x8000_0000_0000_0000_0000_0000_0000_0000,
1689 true,
1690 );
1691
1692 assert_ok::<U0F128>("-0", 16, 0x0000_0000_0000_0000_0000_0000_0000_0000, false);
1693 assert_ok::<U0F128>(
1694 "0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7",
1695 16,
1696 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1697 false,
1698 );
1699 assert_ok::<U0F128>(
1700 "0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
1701 16,
1702 0x8000_0000_0000_0000_0000_0000_0000_0000,
1703 false,
1704 );
1705 assert_ok::<U0F128>(
1706 "0.FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7",
1707 16,
1708 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1709 false,
1710 );
1711 assert_ok::<U0F128>(
1712 "0.FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
1713 16,
1714 0x0000_0000_0000_0000_0000_0000_0000_0000,
1715 true,
1716 );
1717 assert_ok::<U0F128>("1", 16, 0x0000_0000_0000_0000_0000_0000_0000_0000, true);
1718
1719 assert_ok::<U64F64>(
1720 "7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF7",
1721 16,
1722 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1723 false,
1724 );
1725 assert_ok::<U64F64>(
1726 "7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8",
1727 16,
1728 0x8000_0000_0000_0000_0000_0000_0000_0000,
1729 false,
1730 );
1731 assert_ok::<U64F64>(
1732 "FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF7",
1733 16,
1734 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1735 false,
1736 );
1737 assert_ok::<U64F64>(
1738 "FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8",
1739 16,
1740 0x0000_0000_0000_0000_0000_0000_0000_0000,
1741 true,
1742 );
1743
1744 assert_ok::<U128F0>(
1745 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.7",
1746 16,
1747 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1748 false,
1749 );
1750 assert_ok::<U128F0>(
1751 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8",
1752 16,
1753 0x8000_0000_0000_0000_0000_0000_0000_0000,
1754 false,
1755 );
1756 assert_ok::<U128F0>(
1757 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.7",
1758 16,
1759 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
1760 false,
1761 );
1762 assert_ok::<U128F0>(
1763 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8",
1764 16,
1765 0x0000_0000_0000_0000_0000_0000_0000_0000,
1766 true,
1767 );
1768 }
1769
1770 struct Fractions {
1776 zero: String,
1777 gt_0: String,
1778 max: String,
1779 over: String,
1780 }
1781 fn without_last(a: &str) -> &str {
1782 &a[..a.len() - 1]
1783 }
1784 fn make_fraction_strings(max_int: &str, eps_frac: &str) -> Fractions {
1785 let eps_frac_compl: String = eps_frac
1786 .chars()
1787 .map(|digit| (b'0' + b'9' - digit as u8) as char)
1788 .collect();
1789
1790 let zero = String::from("0.") + eps_frac;
1791 let gt_0 = String::from(&*zero) + "000001";
1792 let max = String::from(max_int) + &eps_frac_compl + "999999";
1793 let over = String::from(max_int) + without_last(&eps_frac_compl) + "5";
1794 Fractions {
1795 zero,
1796 gt_0,
1797 max,
1798 over,
1799 }
1800 }
1801
1802 #[test]
1808 fn check_exact_decimal() {
1809 let max_int_0 = String::from("0.");
1810 let max_int_4 = String::from("15.");
1811 let max_int_8 = format!("{}.", !0u8);
1812 let max_int_16 = format!("{}.", !0u16);
1813 let max_int_28 = format!("{}.", !0u32 >> 4);
1814 let max_int_32 = format!("{}.", !0u32);
1815 let max_int_64 = format!("{}.", !0u64);
1816 let max_int_124 = format!("{}.", !0u128 >> 4);
1817 let max_int_128 = format!("{}.", !0u128);
1818
1819 let eps_0 = "5";
1832 let eps_4 = "03125";
1833 let eps_8 = "001953125";
1834 let eps_16 = "00000762939453125";
1835 let eps_28 = "00000000186264514923095703125";
1836 let eps_32 = "000000000116415321826934814453125";
1837 let eps_64 = "00000000000000000002710505431213761085018632002174854278564453125";
1838 let eps_124 = "0000000000000000000000000000000000000235098870164457501593747307\
1839 4444491355637331113544175043017503412556834518909454345703125";
1840 let eps_128 = "0000000000000000000000000000000000000014693679385278593849609206\
1841 71527807097273331945965109401885939632848021574318408966064453125";
1842
1843 let frac_0_8 = make_fraction_strings(&max_int_0, eps_8);
1844 assert_ok::<U0F8>(&frac_0_8.zero, 10, 0, false);
1845 assert_ok::<U0F8>(&frac_0_8.gt_0, 10, 1, false);
1846 assert_ok::<U0F8>(&frac_0_8.max, 10, !0, false);
1847 assert_ok::<U0F8>(&frac_0_8.over, 10, 0, true);
1848
1849 let frac_4_4 = make_fraction_strings(&max_int_4, eps_4);
1850 assert_ok::<U4F4>(&frac_4_4.zero, 10, 0, false);
1851 assert_ok::<U4F4>(&frac_4_4.gt_0, 10, 1, false);
1852 assert_ok::<U4F4>(&frac_4_4.max, 10, !0, false);
1853 assert_ok::<U4F4>(&frac_4_4.over, 10, 0, true);
1854
1855 let frac_8_0 = make_fraction_strings(&max_int_8, eps_0);
1856 assert_ok::<U8F0>(&frac_8_0.zero, 10, 0, false);
1857 assert_ok::<U8F0>(&frac_8_0.gt_0, 10, 1, false);
1858 assert_ok::<U8F0>(&frac_8_0.max, 10, !0, false);
1859 assert_ok::<U8F0>(&frac_8_0.over, 10, 0, true);
1860
1861 let frac_0_32 = make_fraction_strings(&max_int_0, eps_32);
1862 assert_ok::<U0F32>(&frac_0_32.zero, 10, 0, false);
1863 assert_ok::<U0F32>(&frac_0_32.gt_0, 10, 1, false);
1864 assert_ok::<U0F32>(&frac_0_32.max, 10, !0, false);
1865 assert_ok::<U0F32>(&frac_0_32.over, 10, 0, true);
1866
1867 let frac_4_28 = make_fraction_strings(&max_int_4, eps_28);
1868 assert_ok::<U4F28>(&frac_4_28.zero, 10, 0, false);
1869 assert_ok::<U4F28>(&frac_4_28.gt_0, 10, 1, false);
1870 assert_ok::<U4F28>(&frac_4_28.max, 10, !0, false);
1871 assert_ok::<U4F28>(&frac_4_28.over, 10, 0, true);
1872
1873 let frac_16_16 = make_fraction_strings(&max_int_16, eps_16);
1874 assert_ok::<U16F16>(&frac_16_16.zero, 10, 0, false);
1875 assert_ok::<U16F16>(&frac_16_16.gt_0, 10, 1, false);
1876 assert_ok::<U16F16>(&frac_16_16.max, 10, !0, false);
1877 assert_ok::<U16F16>(&frac_16_16.over, 10, 0, true);
1878
1879 let frac_28_4 = make_fraction_strings(&max_int_28, eps_4);
1880 assert_ok::<U28F4>(&frac_28_4.zero, 10, 0, false);
1881 assert_ok::<U28F4>(&frac_28_4.gt_0, 10, 1, false);
1882 assert_ok::<U28F4>(&frac_28_4.max, 10, !0, false);
1883 assert_ok::<U28F4>(&frac_28_4.over, 10, 0, true);
1884
1885 let frac_32_0 = make_fraction_strings(&max_int_32, eps_0);
1886 assert_ok::<U32F0>(&frac_32_0.zero, 10, 0, false);
1887 assert_ok::<U32F0>(&frac_32_0.gt_0, 10, 1, false);
1888 assert_ok::<U32F0>(&frac_32_0.max, 10, !0, false);
1889 assert_ok::<U32F0>(&frac_32_0.over, 10, 0, true);
1890
1891 let frac_0_128 = make_fraction_strings(&max_int_0, eps_128);
1892 assert_ok::<U0F128>(&frac_0_128.zero, 10, 0, false);
1893 assert_ok::<U0F128>(&frac_0_128.gt_0, 10, 1, false);
1894 assert_ok::<U0F128>(&frac_0_128.max, 10, !0, false);
1895 assert_ok::<U0F128>(&frac_0_128.over, 10, 0, true);
1896
1897 let frac_4_124 = make_fraction_strings(&max_int_4, eps_124);
1898 assert_ok::<U4F124>(&frac_4_124.zero, 10, 0, false);
1899 assert_ok::<U4F124>(&frac_4_124.gt_0, 10, 1, false);
1900 assert_ok::<U4F124>(&frac_4_124.max, 10, !0, false);
1901 assert_ok::<U4F124>(&frac_4_124.over, 10, 0, true);
1902
1903 let frac_64_64 = make_fraction_strings(&max_int_64, eps_64);
1904 assert_ok::<U64F64>(&frac_64_64.zero, 10, 0, false);
1905 assert_ok::<U64F64>(&frac_64_64.gt_0, 10, 1, false);
1906 assert_ok::<U64F64>(&frac_64_64.max, 10, !0, false);
1907 assert_ok::<U64F64>(&frac_64_64.over, 10, 0, true);
1908
1909 let frac_124_4 = make_fraction_strings(&max_int_124, eps_4);
1910 assert_ok::<U124F4>(&frac_124_4.zero, 10, 0, false);
1911 assert_ok::<U124F4>(&frac_124_4.gt_0, 10, 1, false);
1912 assert_ok::<U124F4>(&frac_124_4.max, 10, !0, false);
1913 assert_ok::<U124F4>(&frac_124_4.over, 10, 0, true);
1914
1915 let frac_128_0 = make_fraction_strings(&max_int_128, eps_0);
1916 assert_ok::<U128F0>(&frac_128_0.zero, 10, 0, false);
1917 assert_ok::<U128F0>(&frac_128_0.gt_0, 10, 1, false);
1918 assert_ok::<U128F0>(&frac_128_0.max, 10, !0, false);
1919 assert_ok::<U128F0>(&frac_128_0.over, 10, 0, true);
1920
1921 assert_ok::<U4F4>(
1924 "0.40624999999999999999999999999999999999999999999999",
1925 10,
1926 0x06,
1927 false,
1928 );
1929 assert_ok::<U4F4>("0.40625", 10, 0x06, false);
1930 assert_ok::<U4F4>(
1931 "0.40625000000000000000000000000000000000000000000001",
1932 10,
1933 0x07,
1934 false,
1935 );
1936 assert_ok::<U4F4>("0.4375", 10, 0x07, false);
1938 assert_ok::<U4F4>(
1940 "0.46874999999999999999999999999999999999999999999999",
1941 10,
1942 0x07,
1943 false,
1944 );
1945 assert_ok::<U4F4>("0.46875", 10, 0x08, false);
1946 assert_ok::<U4F4>(
1947 "0.46875000000000000000000000000000000000000000000001",
1948 10,
1949 0x08,
1950 false,
1951 );
1952 assert_ok::<U4F4>("0.5", 10, 0x08, false);
1954 assert_ok::<U4F4>(
1956 "0.53124999999999999999999999999999999999999999999999",
1957 10,
1958 0x08,
1959 false,
1960 );
1961 assert_ok::<U4F4>("0.53125", 10, 0x08, false);
1962 assert_ok::<U4F4>(
1963 "0.53125000000000000000000000000000000000000000000001",
1964 10,
1965 0x09,
1966 false,
1967 );
1968 assert_ok::<U4F4>("0.5625", 10, 0x09, false);
1970 }
1971
1972 #[test]
1973 fn frac4() {
1974 for u in 0..=255u8 {
1975 let (ifix, ufix) = (I4F4::from_bits(u as i8), U4F4::from_bits(u));
1976 let (ifix_str, ufix_str) = (ifix.to_string(), ufix.to_string());
1977 assert_eq!(I4F4::from_str(&ifix_str).unwrap(), ifix);
1978 assert_eq!(U4F4::from_str(&ufix_str).unwrap(), ufix);
1979 }
1980 }
1981
1982 fn similar<F: Fixed, G: ToFixed>(a: F, b: F, max_diff: G) -> bool {
1983 let abs_diff = if a > b { a - b } else { b - a };
1984 abs_diff <= max_diff.to_fixed::<F>()
1985 }
1986
1987 #[test]
1988 fn frac17() {
1989 for u in 0..(1 << 17) {
1990 let fix = U15F17::from_bits(u) + U15F17::from_num(99);
1991 let fix_pos = I15F17::from_num(fix);
1992 let fix_neg = -fix_pos;
1993 let fix_str = fix.to_string();
1994 let fix_pos_str = fix_pos.to_string();
1995 let fix_neg_str = fix_neg.to_string();
1996 assert_eq!(fix_str, fix_pos_str);
1997 if u != 0 {
1998 assert_eq!(&fix_neg_str[..1], "-");
1999 assert_eq!(&fix_neg_str[1..], fix_pos_str);
2000 }
2001 assert_eq!(U15F17::from_str(&fix_str).unwrap(), fix);
2002 assert_eq!(I15F17::from_str(&fix_pos_str).unwrap(), fix_pos);
2003 assert_eq!(I15F17::from_str(&fix_neg_str).unwrap(), fix_neg);
2004
2005 let fix_str3 = format!("{:.3}", fix);
2006 let fix_pos_str3 = format!("{:.3}", fix_pos);
2007 let fix_neg_str3 = format!("{:.3}", fix_neg);
2008 assert_eq!(fix_str3, fix_pos_str3);
2009 if u != 0 {
2010 assert_eq!(&fix_neg_str3[..1], "-");
2011 assert_eq!(&fix_neg_str3[1..], fix_pos_str3);
2012 }
2013 let max_diff = U15F17::from_bits((5 << 17) / 10000 + 1);
2014 let from_fix_str3 = U15F17::from_str(&fix_str3).unwrap();
2015 assert!(similar(from_fix_str3, fix, max_diff));
2016 let from_fix_pos_str3 = I15F17::from_str(&fix_pos_str3).unwrap();
2017 assert!(similar(from_fix_pos_str3, fix_pos, max_diff));
2018 let from_fix_neg_str3 = I15F17::from_str(&fix_neg_str3).unwrap();
2019 assert!(similar(from_fix_neg_str3, fix_neg, max_diff));
2020
2021 let fix_str9 = format!("{:.9}", fix);
2022 let fix_pos_str9 = format!("{:.9}", fix_pos);
2023 let fix_neg_str9 = format!("{:.9}", fix_neg);
2024 assert_eq!(fix_str9, fix_pos_str9);
2025 if u != 0 {
2026 assert_eq!(&fix_neg_str9[..1], "-");
2027 assert_eq!(&fix_neg_str9[1..], fix_pos_str9);
2028 }
2029 assert_eq!(U15F17::from_str(&fix_str9).unwrap(), fix);
2030 assert_eq!(I15F17::from_str(&fix_pos_str9).unwrap(), fix_pos);
2031 assert_eq!(I15F17::from_str(&fix_neg_str9).unwrap(), fix_neg);
2032 }
2033 }
2034}