substrate_fixed/
from_str.rs

1// Copyright © 2018–2019 Trevor Spiteri
2
3// This library is free software: you can redistribute it and/or
4// modify it under the terms of either
5//
6//   * the Apache License, Version 2.0 or
7//   * the MIT License
8//
9// at your option.
10//
11// You should have recieved copies of the Apache License and the MIT
12// License along with the library. If not, see
13// <https://www.apache.org/licenses/LICENSE-2.0> and
14// <https://opensource.org/licenses/MIT>.
15
16use 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                // half bit is true, round up if we have more
64                // significant bits or currently acc is odd
65                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                // half bit is true, round up if we have more
120                // significant bits or currently acc is odd
121                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    // We know that byte is a valid hex:
138    //   * b'0'..=b'9' (0x30..=0x39) => byte & 0x0f
139    //   * b'A'..=b'F' (0x41..=0x46) => byte & 0x0f + 9
140    //   * b'a'..=b'f' (0x61..=0x66) => byte & 0x0f + 9
141    (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                // half bit is true, round up if we have more
184                // significant bits or currently acc is odd
185                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
225// Decode fractional decimal digits into nbits fractional bits.
226//
227// For an output with BIN = 8 bits, we can take DEC = 3 decimal digits.
228//
229//     0 ≤ val ≤ 999, 0 ≤ nbits ≤ 8
230//
231// In general,
232//
233//     0 ≤ val ≤ 10^DEC - 1, 0 ≤ nbits ≤ BIN
234//
235// We can either floor the result or round to the nearest, with ties
236// rounded to even. If rounding results in more than nbits bits,
237// returns None.
238//
239// Examples: (for DEC = 3, BIN = 8)
240//
241//    dec_to_bin(999, 8, Round::Floor) -> floor(999 × 256 / 1000) -> 255 -> Some(255)
242//    dec_to_bin(999, 8, Round::Nearest) -> floor(999 × 256 / 1000 + 0.5) -> 256 -> None
243//    dec_to_bin(999, 5, Round::Floor) -> floor(999 × 32 / 1000) -> 31 -> Some(31)
244//    dec_to_bin(999, 5, Round::Nearest) -> floor(999 × 32 / 1000 + 0.5) -> 32 -> None
245//    dec_to_bin(499, 0, Round::Floor) -> floor(499 / 1000) -> 0 -> Some(0)
246//    dec_to_bin(499, 0, Round::Nearest) -> floor(499 / 1000 + 0.5) -> 0 -> Some(0)
247//    dec_to_bin(500, 0, Round::Nearest) -> floor(500 / 1000 + 0.5) -> 1 -> None
248//
249// For flooring:
250//
251//     floor(val × 2^nbits / 10^3) = floor(val × 2^(nbits - 3) / 5^3)
252//
253// For rounding:
254//
255//     floor(val × 2^nbits / 10^3 + 0.5) = floor((val × 2^(nbits - 2) + 5^3) / (2 × 5^3))
256//
257// Using integer arithmetic, this is equal to:
258//
259//     ((val << 6 >> (8 - nbits)) + if rounding { 125 } else { 0 }) / 250
260//
261// Note that val << 6 cannot overflow u16, as val < 1000 and 1000 × 2^6 < 2^16.
262//
263// In general:
264//
265//     ((val << (BIN - DEC + 1) >> (8 - nbits)) + if rounding { 5^DEC } else { 0 }) / (2 × 5^DEC)
266//
267// And we ensure that 10^DEC × 2^(BIN - DEC + 1) < 2^(2 × BIN), which simplifies to
268//
269//     5^DEC × 2 < 2^BIN
270//
271// From this it also follows that val << (BIN - DEC + 1) never overflows a (2 × BIN)-bit number.
272//
273// So for u8, BIN = 8, DEC  3
274// So for u16, BIN = 16, DEC ≤ 6
275// So for u32, BIN = 32, DEC ≤ 13
276// So for u64, BIN = 64, DEC ≤ 27
277// So for u128, BIN = 128, DEC ≤ 54
278trait 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                        // Round up, then round back down if we had a tie and the result is odd.
297                        numer += fives;
298                        // If unrounded division == 1 exactly, we actually have a tie at upper
299                        // bound, which is rounded up to 1.0. This is even in all cases except
300                        // when nbits == 0, in which case we must round it back down to 0.
301                        if numer >> nbits >= denom {
302                            // 0.5 exactly is 10^$dec / 2 = 5^dec * 2^dec / 2 = fives << ($dec - 1)
303                            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        // we need to combine (10^27*hi + lo) << (128 - 54 + 1)
346        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                // Round up, then round back down if we had a tie and the result is odd.
366                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 unrounded division == 1 exactly, we actually have a tie at upper
379                // bound, which is rounded up to 1.0. This is even in all cases except
380                // when nbits == 0, in which case we must round it back down to 0.
381                if check_overflow >= denom {
382                    // 0.5 exactly is 10^$dec / 2 = 5^dec * 2^dec / 2 = fives << ($dec - 1)
383                    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    // if is_short, dec_to_bin can round and give correct answer immediately
428    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    // since !is_short, we have a floor and we have to check whether we need to increment
438
439    // add_5 is to add rounding when all bits are used
440    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            // since zeros are trimmed in bytes, there must be some byte > 0 eventually
451            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/**
513An error which can be returned when parsing a fixed-point number.
514
515# Examples
516
517```rust
518use substrate_fixed::{types::I16F16, ParseFixedError};
519// This string is not a fixed-point number.
520let s = "something completely different (_!_!_)";
521let error: ParseFixedError = match s.parse::<I16F16>() {
522    Ok(_) => unreachable!(),
523    Err(error) => error,
524};
525println!("Parse error: {}", error);
526```
527*/
528#[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
573// also trims zeros at start of int and at end of frac
574fn 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    // since zeros are trimmed, there must be exatly one byte
640    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            /// Parses a string slice to return a fixed-point number.
656            ///
657            /// Rounding is to the nearest, with ties rounded to even.
658            #[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            // frac_overflow does not catch the case where:
755            //  1. int is odd
756            //  2. frac_nbits is 0
757            //  3. frac_bytes is exactly half, e.g. "5" for decimal
758            // In this case, get_frac returns 0.5 rounded to even 0.0,
759            // as it does not have a way to know that int is odd.
760            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        // exact tie, round up to even
1146        assert_ok::<I8F0>("-128.5", 10, -0x80, false);
1147        assert_ok::<I8F0>("127.499", 10, 0x7F, false);
1148        // exact tie, round up to even
1149        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        // exact tie, round up to even
1165        assert_ok::<U8F0>("127.5", 10, 0x80, false);
1166        assert_ok::<U8F0>("255.499", 10, 0xFF, false);
1167        // exact tie, round up to even
1168        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        // exact tie, round up to even
1187        assert_ok::<I16F0>("-32768.5", 10, -0x8000, false);
1188        assert_ok::<I16F0>("+32767.499999", 10, 0x7FFF, false);
1189        // exact tie, round up to even
1190        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        // exact tie, round up to even
1206        assert_ok::<U16F0>("32767.5", 10, 0x8000, false);
1207        assert_ok::<U16F0>("65535.499999", 10, 0xFFFF, false);
1208        // exact tie, round up to even
1209        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        // exact tie, round up to even
1228        assert_ok::<I32F0>("-2147483648.5", 10, -0x8000_0000, false);
1229        assert_ok::<I32F0>("2147483647.4999999999", 10, 0x7FFF_FFFF, false);
1230        // exact tie, round up to even
1231        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        // exact tie, round up to even
1247        assert_ok::<U32F0>("2147483647.5", 10, 0x8000_0000, false);
1248        assert_ok::<U32F0>("4294967295.4999999999", 10, 0xFFFF_FFFF, false);
1249        // exact tie, round up to even
1250        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        // exact tie, round up to even
1274        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        // exact tie, round up to even
1282        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        // exact tie, round up to even
1303        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        // exact tie, round up to even
1311        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        // exact tie, round up to even
1375        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        // exact tie, round up to even
1388        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        // exact tie, round up to even
1454        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        // exact tie, round up to even
1467        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    // For an odd prefix, e.g. eps = 0.125
1771    // zero = 0.125
1772    // gt_0 = 0.125000001
1773    // max = max_int.874999999
1774    // overflow = max_int.875
1775    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    // check that for example for four fractional bits,
1803    //   * 0.03125 (1/32) is parsed as 0
1804    //   * 0.03125000001 (just above 1/32) is parsed as 0.0625 (1/16)
1805    //   * odd.96874999999 (just below 31/32) is parsed as 0.9375 (15/16)
1806    //   * odd.96875 (31/32) is parsed as odd + 1
1807    #[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        // Note: fractions can be generated with this:
1820        //
1821        //     use rug::Integer;
1822        //     for &i in &[0, 4, 8, 16, 28, 32, 64, 124, 128] {
1823        //         let eps = Integer::from(Integer::u_pow_u(5, i + 1));
1824        //         println!("let eps_{} = \"{:02$}\";", i, eps, i as usize + 1);
1825        //     }
1826
1827        // eps_0 = 0.5 >> 0 = 0.5
1828        // eps_4 = 0.5 >> 4 = 0.03125
1829        // eps_8 = 0.5 >> 8 = 0.001953125
1830        // etc.
1831        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        // some other cases
1922        // 13/32 = 6.5/16, to even 6/16
1923        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        // 14/32 = 7/16
1937        assert_ok::<U4F4>("0.4375", 10, 0x07, false);
1938        // 15/32 = 7.5/16, to even 8/16
1939        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        // 16/32 = 8/16
1953        assert_ok::<U4F4>("0.5", 10, 0x08, false);
1954        // 17/32 = 8.5/16, to even 8/16
1955        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        // 18/32 = 9/16
1969        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}