diff --git a/src/from_str.rs b/src/from_str.rs index 4853bfd..8996a89 100644 --- a/src/from_str.rs +++ b/src/from_str.rs @@ -52,11 +52,16 @@ where let dump_bits = I::NBITS - nbits; let mut rem_bits = nbits; let mut acc = I::ZERO; - for &byte in bytes { + for (i, &byte) in bytes.iter().enumerate() { let val = byte - b'0'; if rem_bits < 1 { - // round - acc = acc.checked_add(I::from(val))?; + if val != 0 { + // half bit is true, round up if we have more + // significant bits or currently acc is odd + if bytes.len() > i + 1 || acc.is_odd() { + acc = acc.checked_add(I::from(1))?; + } + } if dump_bits != 0 && acc >> nbits != I::ZERO { return None; } @@ -91,12 +96,18 @@ where let dump_bits = I::NBITS - nbits; let mut rem_bits = nbits; let mut acc = I::ZERO; - for &byte in bytes { + for (i, &byte) in bytes.iter().enumerate() { let val = byte - b'0'; if rem_bits < 3 { acc = (acc << rem_bits) + I::from(val >> (3 - rem_bits)); - // round - acc = acc.checked_add(I::from((val >> (2 - rem_bits)) & 1))?; + let half = 1 << (2 - rem_bits); + if val & half != 0 { + // half bit is true, round up if we have more + // significant bits or currently acc is odd + if val & (half - 1) != 0 || bytes.len() > i + 1 || acc.is_odd() { + acc = acc.checked_add(I::from(1))?; + } + } if dump_bits != 0 && acc >> nbits != I::ZERO { return None; } @@ -139,12 +150,18 @@ where let dump_bits = I::NBITS - nbits; let mut rem_bits = nbits; let mut acc = I::ZERO; - for &byte in bytes { + for (i, &byte) in bytes.iter().enumerate() { let val = unchecked_hex_digit(byte); if rem_bits < 4 { acc = (acc << rem_bits) + I::from(val >> (4 - rem_bits)); - // round - acc = acc.checked_add(I::from((val >> (3 - rem_bits)) & 1))?; + let half = 1 << (3 - rem_bits); + if val & half != 0 { + // half bit is true, round up if we have more + // significant bits or currently acc is odd + if val & (half - 1) != 0 || bytes.len() > i + 1 || acc.is_odd() { + acc = acc.checked_add(I::from(1))?; + } + } if dump_bits != 0 && acc >> nbits != I::ZERO { return None; } @@ -536,121 +553,132 @@ fn parse_bounds(bytes: &[u8], can_be_neg: bool, radix: u32) -> Result, Ok(Parse { neg, int, frac }) } +fn frac_is_half(bytes: &[u8], radix: u32) -> bool { + // since zeros are trimmed, there must be exatly one byte + bytes.len() == 1 && bytes[0] - b'0' == (radix as u8) / 2 +} + pub(crate) trait FromStrRadix: Sized { type Err; fn from_str_radix(s: &str, radix: u32) -> Result; } macro_rules! impl_from_str { - ($Fixed:ident, $LeEqU:ident, $method:ident) => { - impl FromStr for $Fixed { + ( + $FixedI:ident($BitsI:ident), $FixedU:ident($BitsU:ident), $LeEqU:ident; + fn $from_i:ident; + fn $from_u:ident; + fn $get_int_frac:ident; + fn $get_int:ident, ($get_int_half:ident, $attempt_int_half:expr); + fn $get_frac:ident, ($get_frac_half:ident, $attempt_frac_half:expr); + ) => { + impl FromStr for $FixedI { type Err = ParseFixedError; #[inline] fn from_str(s: &str) -> Result { - $method(s.as_bytes(), 10, Self::INT_NBITS, Self::FRAC_NBITS).map(Self::from_bits) + $from_i(s.as_bytes(), 10, Self::INT_NBITS, Self::FRAC_NBITS).map(Self::from_bits) } } - impl FromStrRadix for $Fixed { + impl FromStrRadix for $FixedI { type Err = ParseFixedError; #[inline] fn from_str_radix(s: &str, radix: u32) -> Result { - $method(s.as_bytes(), radix, Self::INT_NBITS, Self::FRAC_NBITS).map(Self::from_bits) + $from_i(s.as_bytes(), radix, Self::INT_NBITS, Self::FRAC_NBITS).map(Self::from_bits) + } + } + impl FromStr for $FixedU { + type Err = ParseFixedError; + #[inline] + fn from_str(s: &str) -> Result { + $from_u(s.as_bytes(), 10, Self::INT_NBITS, Self::FRAC_NBITS).map(Self::from_bits) + } + } + impl FromStrRadix for $FixedU { + type Err = ParseFixedError; + #[inline] + fn from_str_radix(s: &str, radix: u32) -> Result { + $from_u(s.as_bytes(), radix, Self::INT_NBITS, Self::FRAC_NBITS).map(Self::from_bits) } } - }; -} -macro_rules! impl_from_str_signed { - ( - $Fixed:ident, $LeEqU:ident, $Bits:ident; - fn $all:ident; - $int:ident; - $frac:ident; - ) => { - impl_from_str! { $Fixed, $LeEqU, $all } - - fn $all( + fn $from_i( bytes: &[u8], radix: u32, int_nbits: u32, frac_nbits: u32, - ) -> Result<$Bits, ParseFixedError> { - let Parse { neg, int, frac } = parse_bounds(bytes, true, radix)?; - let (abs_frac, whole_frac) = match $frac(frac, radix, frac_nbits) { - Some(frac) => (frac, false), - None => (0, true), - }; - let abs_int = - $int(int, radix, int_nbits, whole_frac).ok_or(ParseErrorKind::Overflow)?; - let abs = abs_int | abs_frac; - let max_abs = if neg { - <$Bits as IntHelper>::Unsigned::MSB + ) -> Result<$BitsI, ParseFixedError> { + let (neg, abs) = $get_int_frac(bytes, true, radix, int_nbits, frac_nbits)?; + if neg { + if abs > $BitsU::MSB { + Err(ParseErrorKind::Overflow.into()) + } else { + Ok(abs.wrapping_neg() as $BitsI) + } } else { - <$Bits as IntHelper>::Unsigned::MSB - 1 - }; - if abs > max_abs { - Err(ParseErrorKind::Overflow)?; + if abs > $BitsU::MSB - 1 { + Err(ParseErrorKind::Overflow.into()) + } else { + Ok(abs as $BitsI) + } } - let f = if neg { - abs.wrapping_neg() as $Bits - } else { - abs as $Bits - }; - Ok(f) } - }; -} -macro_rules! impl_from_str_unsigned { - ( - $Fixed:ident, $LeEqU:ident, $Bits:ident; - fn $all:ident; - fn $int:ident, ($int_half:ident, $int_half_cond:expr); - fn $frac:ident, ($frac_half:ident, $frac_half_cond:expr); - ) => { - impl_from_str! { $Fixed, $LeEqU, $all } - - fn $all( + fn $from_u( bytes: &[u8], radix: u32, int_nbits: u32, frac_nbits: u32, - ) -> Result<$Bits, ParseFixedError> { - let Parse { int, frac, .. } = parse_bounds(bytes, false, radix)?; - let (frac, whole_frac) = match $frac(frac, radix, frac_nbits) { - Some(frac) => (frac, false), - None => (0, true), - }; - let int = $int(int, radix, int_nbits, whole_frac).ok_or(ParseErrorKind::Overflow)?; - Ok(int | frac) + ) -> Result<$BitsU, ParseFixedError> { + let (_, abs) = $get_int_frac(bytes, false, radix, int_nbits, frac_nbits)?; + Ok(abs) } - fn $int(int: &[u8], radix: u32, nbits: u32, whole_frac: bool) -> Option<$Bits> { - const HALF: u32 = <$Bits as IntHelper>::NBITS / 2; - if $int_half_cond && nbits <= HALF { - return $int_half(int, radix, nbits, whole_frac).map(|x| $Bits::from(x) << HALF); + fn $get_int_frac( + bytes: &[u8], + can_be_neg: bool, + radix: u32, + int_nbits: u32, + frac_nbits: u32, + ) -> Result<(bool, $BitsU), ParseFixedError> { + let Parse { neg, int, frac } = parse_bounds(bytes, can_be_neg, radix)?; + let int_val = $get_int(int, radix, int_nbits).ok_or(ParseErrorKind::Overflow)?; + let (frac_val, frac_overflow) = match $get_frac(frac, radix, frac_nbits) { + Some(val) => (val, false), + None => (0, true), + }; + if frac_overflow && int_nbits == 0 { + return Err(ParseErrorKind::Overflow.into()); + } + let val = int_val | frac_val; + // round up if int is odd, frac_nbits is 0, and frac_bytes is exactly half + if frac_overflow || (int_val.is_odd() && frac_nbits == 0 && frac_is_half(frac, radix)) { + val.checked_add(1 << frac_nbits) + .map(|val| (neg, val)) + .ok_or(ParseErrorKind::Overflow.into()) + } else { + Ok((neg, val)) + } + } + + fn $get_int(int: &[u8], radix: u32, nbits: u32) -> Option<$BitsU> { + const HALF: u32 = <$BitsU as IntHelper>::NBITS / 2; + if $attempt_int_half && nbits <= HALF { + return $get_int_half(int, radix, nbits).map(|x| $BitsU::from(x) << HALF); } - if int.is_empty() && !whole_frac { + if int.is_empty() { return Some(0); - } else if int.is_empty() && nbits != 0 { - return Some(1); - } else if int.is_empty() { - return None; } else if nbits == 0 { return None; } - let mut parsed_int: $Bits = match radix { + let parsed_int: $BitsU = match radix { 2 => bin_str_int_to_bin(int)?, 8 => oct_str_int_to_bin(int)?, 16 => hex_str_int_to_bin(int)?, 10 => dec_str_int_to_bin(int)?, _ => unreachable!(), }; - if whole_frac { - parsed_int = parsed_int.checked_add(1)?; - } - let remove_bits = <$Bits as IntHelper>::NBITS - nbits; + let remove_bits = <$BitsU as IntHelper>::NBITS - nbits; if remove_bits > 0 && (parsed_int >> nbits) != 0 { None } else { @@ -658,9 +686,9 @@ macro_rules! impl_from_str_unsigned { } } - fn $frac(frac: &[u8], radix: u32, nbits: u32) -> Option<$Bits> { - if $frac_half_cond && nbits <= <$Bits as IntHelper>::NBITS / 2 { - return $frac_half(frac, radix, nbits).map($Bits::from); + fn $get_frac(frac: &[u8], radix: u32, nbits: u32) -> Option<$BitsU> { + if $attempt_frac_half && nbits <= <$BitsU as IntHelper>::NBITS / 2 { + return $get_frac_half(frac, radix, nbits).map($BitsU::from); } if frac.is_empty() { return Some(0); @@ -676,67 +704,43 @@ macro_rules! impl_from_str_unsigned { }; } -impl_from_str_signed! { - FixedI8, LeEqU8, i8; +impl_from_str! { + FixedI8(i8), FixedU8(u8), LeEqU8; fn from_str_i8; - get_int8; - get_frac8; -} -impl_from_str_unsigned! { - FixedU8, LeEqU8, u8; fn from_str_u8; + fn get_int_frac8; fn get_int8, (get_int8, false); fn get_frac8, (get_frac8, false); } - -impl_from_str_signed! { - FixedI16, LeEqU16, i16; +impl_from_str! { + FixedI16(i16), FixedU16(u16), LeEqU16; fn from_str_i16; - get_int16; - get_frac16; -} -impl_from_str_unsigned! { - FixedU16, LeEqU16, u16; fn from_str_u16; + fn get_int_frac16; fn get_int16, (get_int8, true); fn get_frac16, (get_frac8, true); } - -impl_from_str_signed! { - FixedI32, LeEqU32, i32; +impl_from_str! { + FixedI32(i32), FixedU32(u32), LeEqU32; fn from_str_i32; - get_int32; - get_frac32; -} -impl_from_str_unsigned! { - FixedU32, LeEqU32, u32; fn from_str_u32; + fn get_int_frac32; fn get_int32, (get_int16, true); fn get_frac32, (get_frac16, true); } - -impl_from_str_signed! { - FixedI64, LeEqU64, i64; +impl_from_str! { + FixedI64(i64), FixedU64(u64), LeEqU64; fn from_str_i64; - get_int64; - get_frac64; -} -impl_from_str_unsigned! { - FixedU64, LeEqU64, u64; fn from_str_u64; + fn get_int_frac64; fn get_int64, (get_int32, true); - fn get_frac64, (get_frac32, true); + fn get_frac64, (get_frac32, false); } - -impl_from_str_signed! { - FixedI128, LeEqU128, i128; +impl_from_str! { + FixedI128(i128), FixedU128(u128), LeEqU128; fn from_str_i128; - get_int128; - get_frac128; -} -impl_from_str_unsigned! { - FixedU128, LeEqU128, u128; fn from_str_u128; + fn get_int_frac128; fn get_int128, (get_int64, true); fn get_frac128, (get_frac64, true); } @@ -903,11 +907,11 @@ mod tests { F::Bits: Eq + Debug, { match F::from_str(s) { - Ok(f) => assert_eq!(f.to_bits(), bits), + Ok(f) => assert_eq!(f.to_bits(), bits, "parsed {} as {}", s, f), Err(e) => panic!("could not parse {}: {}", s, e), } } - fn assert_err(s: &str, kind: ParseErrorKind) + fn assert_er(s: &str, kind: ParseErrorKind) where F: Fixed + FromStr, { @@ -923,11 +927,11 @@ mod tests { F::Bits: Eq + Debug, { match ::from_str_radix(s, radix) { - Ok(f) => assert_eq!(f.to_bits(), bits), + Ok(f) => assert_eq!(f.to_bits(), bits, "parsed {} as {}", s, f), Err(e) => panic!("could not parse {}: {}", s, e), } } - fn assert_err_radix(s: &str, radix: u32, kind: ParseErrorKind) + fn assert_er_radix(s: &str, radix: u32, kind: ParseErrorKind) where F: Fixed + FromStrRadix, { @@ -939,241 +943,250 @@ mod tests { #[test] fn check_i8_u8_from_str() { - assert_err::("-1", ParseErrorKind::Overflow); - assert_err::("-0.502", ParseErrorKind::Overflow); + assert_er::("-1", ParseErrorKind::Overflow); + assert_er::("-0.502", ParseErrorKind::Overflow); assert_ok::("-0.501", -0x80); assert_ok::("0.498", 0x7F); - assert_err::("0.499", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.499", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); - assert_err::("-8.04", ParseErrorKind::Overflow); + assert_er::("-8.04", ParseErrorKind::Overflow); assert_ok::("-8.03", -0x80); assert_ok::("7.96", 0x7F); - assert_err::("7.97", ParseErrorKind::Overflow); + assert_er::("7.97", ParseErrorKind::Overflow); - assert_err::("-128.5", ParseErrorKind::Overflow); + assert_er::("-128.5", ParseErrorKind::Overflow); assert_ok::("-128.499", -0x80); assert_ok::("127.499", 0x7F); - assert_err::("127.5", ParseErrorKind::Overflow); + assert_er::("127.5", ParseErrorKind::Overflow); - assert_err::("-0", ParseErrorKind::InvalidDigit); + assert_er::("-0", ParseErrorKind::InvalidDigit); assert_ok::("0.498", 0x7F); assert_ok::("0.499", 0x80); assert_ok::("0.998", 0xFF); - assert_err::("0.999", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.999", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); assert_ok::("7.96", 0x7F); assert_ok::("7.97", 0x80); assert_ok::("15.96", 0xFF); - assert_err::("15.97", ParseErrorKind::Overflow); + assert_er::("15.97", ParseErrorKind::Overflow); assert_ok::("127.499", 0x7F); assert_ok::("127.5", 0x80); assert_ok::("255.499", 0xFF); - assert_err::("255.5", ParseErrorKind::Overflow); + assert_er::("255.5", ParseErrorKind::Overflow); } #[test] fn check_i16_u16_from_str() { - assert_err::("-1", ParseErrorKind::Overflow); - assert_err::("-0.500008", ParseErrorKind::Overflow); + assert_er::("-1", ParseErrorKind::Overflow); + assert_er::("-0.500008", ParseErrorKind::Overflow); assert_ok::("-0.500007", -0x8000); assert_ok::("0.499992", 0x7FFF); - assert_err::("0.499993", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.499993", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); - assert_err::("-128.002", ParseErrorKind::Overflow); + assert_er::("-128.002", ParseErrorKind::Overflow); assert_ok::("-128.001", -0x8000); assert_ok::("127.998", 0x7FFF); - assert_err::("127.999", ParseErrorKind::Overflow); + assert_er::("127.999", ParseErrorKind::Overflow); - assert_err::("-32768.5", ParseErrorKind::Overflow); + assert_er::("-32768.5", ParseErrorKind::Overflow); assert_ok::("-32768.499999", -0x8000); assert_ok::("32767.499999", 0x7FFF); - assert_err::("32767.5", ParseErrorKind::Overflow); + assert_er::("32767.5", ParseErrorKind::Overflow); - assert_err::("-0", ParseErrorKind::InvalidDigit); + assert_er::("-0", ParseErrorKind::InvalidDigit); assert_ok::("0.499992", 0x7FFF); assert_ok::("0.499993", 0x8000); assert_ok::("0.999992", 0xFFFF); - assert_err::("0.999993", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.999993", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); assert_ok::("127.998", 0x7FFF); assert_ok::("127.999", 0x8000); assert_ok::("255.998", 0xFFFF); - assert_err::("255.999", ParseErrorKind::Overflow); + assert_er::("255.999", ParseErrorKind::Overflow); assert_ok::("32767.499999", 0x7FFF); assert_ok::("32767.5", 0x8000); assert_ok::("65535.499999", 0xFFFF); - assert_err::("65535.5", ParseErrorKind::Overflow); + assert_er::("65535.5", ParseErrorKind::Overflow); } #[test] fn check_i32_u32_from_str() { - assert_err::("-1", ParseErrorKind::Overflow); - assert_err::("-0.5000000002", ParseErrorKind::Overflow); + assert_er::("-1", ParseErrorKind::Overflow); + assert_er::("-0.5000000002", ParseErrorKind::Overflow); assert_ok::("-0.5000000001", -0x8000_0000); assert_ok::("0.4999999998", 0x7FFF_FFFF); - assert_err::("0.4999999999", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.4999999999", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); - assert_err::("-32768.000008", ParseErrorKind::Overflow); + assert_er::("-32768.000008", ParseErrorKind::Overflow); assert_ok::("-32768.000007", -0x8000_0000); assert_ok::("32767.999992", 0x7FFF_FFFF); - assert_err::("32767.999993", ParseErrorKind::Overflow); + assert_er::("32767.999993", ParseErrorKind::Overflow); - assert_err::("-2147483648.5", ParseErrorKind::Overflow); + assert_er::("-2147483648.5", ParseErrorKind::Overflow); assert_ok::("-2147483648.4999999999", -0x8000_0000); assert_ok::("2147483647.4999999999", 0x7FFF_FFFF); - assert_err::("2147483647.5", ParseErrorKind::Overflow); + assert_er::("2147483647.5", ParseErrorKind::Overflow); - assert_err::("-0", ParseErrorKind::InvalidDigit); + assert_er::("-0", ParseErrorKind::InvalidDigit); assert_ok::("0.4999999998", 0x7FFF_FFFF); assert_ok::("0.4999999999", 0x8000_0000); assert_ok::("0.9999999998", 0xFFFF_FFFF); - assert_err::("0.9999999999", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.9999999999", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); assert_ok::("32767.999992", 0x7FFF_FFFF); assert_ok::("32767.999993", 0x8000_0000); assert_ok::("65535.999992", 0xFFFF_FFFF); - assert_err::("65535.999993", ParseErrorKind::Overflow); + assert_er::("65535.999993", ParseErrorKind::Overflow); assert_ok::("2147483647.4999999999", 0x7FFF_FFFF); assert_ok::("2147483647.5", 0x8000_0000); assert_ok::("4294967295.4999999999", 0xFFFF_FFFF); - assert_err::("4294967295.5", ParseErrorKind::Overflow); + assert_er::("4294967295.5", ParseErrorKind::Overflow); } #[test] fn check_i16_u16_from_str_binary() { - assert_err_radix::("-1", 2, ParseErrorKind::Overflow); - assert_err_radix::("-0.100000000000000010", 2, ParseErrorKind::Overflow); - assert_ok_radix::("-0.100000000000000001", 2, -0x8000); - assert_ok_radix::("0.011111111111111101", 2, 0x7FFF); - assert_err_radix::("0.011111111111111110", 2, ParseErrorKind::Overflow); - assert_err_radix::("1", 2, ParseErrorKind::Overflow); + assert_er_radix::("-1", 2, ParseErrorKind::Overflow); + assert_er_radix::("-0.100000000000000011", 2, ParseErrorKind::Overflow); + assert_ok_radix::("-0.100000000000000010", 2, -0x8000); + assert_ok_radix::("-0.011111111111111110", 2, -0x8000); + assert_ok_radix::("+0.011111111111111101", 2, 0x7FFF); + assert_er_radix::("+0.011111111111111110", 2, ParseErrorKind::Overflow); + assert_er_radix::("1", 2, ParseErrorKind::Overflow); - assert_err_radix::("-10000000.0000000010", 2, ParseErrorKind::Overflow); - assert_ok_radix::("-10000000.0000000001", 2, -0x8000); - assert_ok_radix::("1111111.1111111101", 2, 0x7FFF); - assert_err_radix::("1111111.1111111110", 2, ParseErrorKind::Overflow); + assert_er_radix::("-10000000.0000000011", 2, ParseErrorKind::Overflow); + assert_ok_radix::("-10000000.0000000010", 2, -0x8000); + assert_ok_radix::("-01111111.1111111110", 2, -0x8000); + assert_ok_radix::("+01111111.1111111101", 2, 0x7FFF); + assert_er_radix::("+01111111.1111111110", 2, ParseErrorKind::Overflow); - assert_err_radix::("-1000000000000000.10", 2, ParseErrorKind::Overflow); - assert_ok_radix::("-1000000000000000.01", 2, -0x8000); - assert_ok_radix::("111111111111111.01", 2, 0x7FFF); - assert_err_radix::("111111111111111.10", 2, ParseErrorKind::Overflow); + assert_er_radix::("-1000000000000000.11", 2, ParseErrorKind::Overflow); + assert_ok_radix::("-1000000000000000.10", 2, -0x8000); + assert_ok_radix::("-0111111111111111.10", 2, -0x8000); + assert_ok_radix::("+0111111111111111.01", 2, 0x7FFF); + assert_er_radix::("+0111111111111111.10", 2, ParseErrorKind::Overflow); - assert_err_radix::("-0", 2, ParseErrorKind::InvalidDigit); + assert_er_radix::("-0", 2, ParseErrorKind::InvalidDigit); assert_ok_radix::("0.011111111111111101", 2, 0x7FFF); assert_ok_radix::("0.011111111111111110", 2, 0x8000); assert_ok_radix::("0.111111111111111101", 2, 0xFFFF); - assert_err_radix::("0.111111111111111110", 2, ParseErrorKind::Overflow); - assert_err_radix::("1", 2, ParseErrorKind::Overflow); + assert_er_radix::("0.111111111111111110", 2, ParseErrorKind::Overflow); + assert_er_radix::("1", 2, ParseErrorKind::Overflow); - assert_ok_radix::("1111111.1111111101", 2, 0x7FFF); - assert_ok_radix::("1111111.1111111110", 2, 0x8000); + assert_ok_radix::("01111111.1111111101", 2, 0x7FFF); + assert_ok_radix::("01111111.1111111110", 2, 0x8000); assert_ok_radix::("11111111.1111111101", 2, 0xFFFF); - assert_err_radix::("11111111.1111111110", 2, ParseErrorKind::Overflow); + assert_er_radix::("11111111.1111111110", 2, ParseErrorKind::Overflow); - assert_ok_radix::("111111111111111.01", 2, 0x7FFF); - assert_ok_radix::("111111111111111.10", 2, 0x8000); + assert_ok_radix::("0111111111111111.01", 2, 0x7FFF); + assert_ok_radix::("0111111111111111.10", 2, 0x8000); assert_ok_radix::("1111111111111111.01", 2, 0xFFFF); - assert_err_radix::("1111111111111111.10", 2, ParseErrorKind::Overflow); + assert_er_radix::("1111111111111111.10", 2, ParseErrorKind::Overflow); } #[test] fn check_i16_u16_from_str_octal() { - assert_err_radix::("-1", 8, ParseErrorKind::Overflow); - assert_err_radix::("-0.400002", 8, ParseErrorKind::Overflow); - assert_ok_radix::("-0.400001", 8, -0x8000); - assert_ok_radix::("0.377775", 8, 0x7FFF); - assert_err_radix::("0.377776", 8, ParseErrorKind::Overflow); - assert_err_radix::("1", 8, ParseErrorKind::Overflow); + assert_er_radix::("-1", 8, ParseErrorKind::Overflow); + assert_er_radix::("-0.400003", 8, ParseErrorKind::Overflow); + assert_ok_radix::("-0.400002", 8, -0x8000); + assert_ok_radix::("-0.377776", 8, -0x8000); + assert_ok_radix::("+0.377775", 8, 0x7FFF); + assert_er_radix::("+0.377776", 8, ParseErrorKind::Overflow); + assert_er_radix::("1", 8, ParseErrorKind::Overflow); - assert_err_radix::("-2000.0010", 8, ParseErrorKind::Overflow); - assert_ok_radix::("-200.0007", 8, -0x8000); - assert_ok_radix::("177.7767", 8, 0x7FFF); - assert_err_radix::("177.7770", 8, ParseErrorKind::Overflow); + assert_er_radix::("-200.0011", 8, ParseErrorKind::Overflow); + assert_ok_radix::("-200.0010", 8, -0x8000); + assert_ok_radix::("-177.7770", 8, -0x8000); + assert_ok_radix::("+177.7767", 8, 0x7FFF); + assert_er_radix::("+177.7770", 8, ParseErrorKind::Overflow); - assert_err_radix::("-100000.4", 8, ParseErrorKind::Overflow); - assert_ok_radix::("-100000.3", 8, -0x8000); - assert_ok_radix::("77777.3", 8, 0x7FFF); - assert_err_radix::("77777.4", 8, ParseErrorKind::Overflow); + assert_er_radix::("-100000.5", 8, ParseErrorKind::Overflow); + assert_ok_radix::("-100000.4", 8, -0x8000); + assert_ok_radix::("-077777.4", 8, -0x8000); + assert_ok_radix::("+077777.3", 8, 0x7FFF); + assert_er_radix::("+077777.4", 8, ParseErrorKind::Overflow); - assert_err_radix::("-0", 8, ParseErrorKind::InvalidDigit); + assert_er_radix::("-0", 8, ParseErrorKind::InvalidDigit); assert_ok_radix::("0.377775", 8, 0x7FFF); assert_ok_radix::("0.377776", 8, 0x8000); assert_ok_radix::("0.777775", 8, 0xFFFF); - assert_err_radix::("0.777776", 8, ParseErrorKind::Overflow); - assert_err_radix::("1", 8, ParseErrorKind::Overflow); + assert_er_radix::("0.777776", 8, ParseErrorKind::Overflow); + assert_er_radix::("1", 8, ParseErrorKind::Overflow); assert_ok_radix::("177.7767", 8, 0x7FFF); assert_ok_radix::("177.7770", 8, 0x8000); assert_ok_radix::("377.7767", 8, 0xFFFF); - assert_err_radix::("377.7770", 8, ParseErrorKind::Overflow); + assert_er_radix::("377.7770", 8, ParseErrorKind::Overflow); - assert_ok_radix::("77777.3", 8, 0x7FFF); - assert_ok_radix::("77777.4", 8, 0x8000); + assert_ok_radix::("077777.3", 8, 0x7FFF); + assert_ok_radix::("077777.4", 8, 0x8000); assert_ok_radix::("177777.3", 8, 0xFFFF); - assert_err_radix::("177777.4", 8, ParseErrorKind::Overflow); + assert_er_radix::("177777.4", 8, ParseErrorKind::Overflow); } #[test] fn check_i16_u16_from_str_hex() { - assert_err_radix::("-1", 16, ParseErrorKind::Overflow); - assert_err_radix::("-0.80008", 16, ParseErrorKind::Overflow); - assert_ok_radix::("-0.80007", 16, -0x8000); - assert_ok_radix::("0.7FFF7", 16, 0x7FFF); - assert_err_radix::("0.7FFF8", 16, ParseErrorKind::Overflow); - assert_err_radix::("1", 16, ParseErrorKind::Overflow); + assert_er_radix::("-1", 16, ParseErrorKind::Overflow); + assert_er_radix::("-0.80009", 16, ParseErrorKind::Overflow); + assert_ok_radix::("-0.80008", 16, -0x8000); + assert_ok_radix::("-0.7FFF8", 16, -0x8000); + assert_ok_radix::("+0.7FFF7", 16, 0x7FFF); + assert_er_radix::("+0.7FFF8", 16, ParseErrorKind::Overflow); + assert_er_radix::("1", 16, ParseErrorKind::Overflow); - assert_err_radix::("-80.008", 16, ParseErrorKind::Overflow); - assert_ok_radix::("-80.007", 16, -0x8000); - assert_ok_radix::("7F.FF7", 16, 0x7FFF); - assert_err_radix::("7F.FF8", 16, ParseErrorKind::Overflow); + assert_er_radix::("-80.009", 16, ParseErrorKind::Overflow); + assert_ok_radix::("-80.008", 16, -0x8000); + assert_ok_radix::("-7F.FF8", 16, -0x8000); + assert_ok_radix::("+7F.FF7", 16, 0x7FFF); + assert_er_radix::("+7F.FF8", 16, ParseErrorKind::Overflow); - assert_err_radix::("-8000.8", 16, ParseErrorKind::Overflow); - assert_ok_radix::("-8000.7", 16, -0x8000); - assert_ok_radix::("7FFF.7", 16, 0x7FFF); - assert_err_radix::("7FFF.8", 16, ParseErrorKind::Overflow); + assert_er_radix::("-8000.9", 16, ParseErrorKind::Overflow); + assert_ok_radix::("-8000.8", 16, -0x8000); + assert_ok_radix::("-7FFF.8", 16, -0x8000); + assert_ok_radix::("+7FFF.7", 16, 0x7FFF); + assert_er_radix::("+7FFF.8", 16, ParseErrorKind::Overflow); - assert_err_radix::("-0", 16, ParseErrorKind::InvalidDigit); + assert_er_radix::("-0", 16, ParseErrorKind::InvalidDigit); assert_ok_radix::("0.7FFF7", 16, 0x7FFF); assert_ok_radix::("0.7FFF8", 16, 0x8000); assert_ok_radix::("0.FFFF7", 16, 0xFFFF); - assert_err_radix::("0.FFFF8", 16, ParseErrorKind::Overflow); - assert_err_radix::("1", 16, ParseErrorKind::Overflow); + assert_er_radix::("0.FFFF8", 16, ParseErrorKind::Overflow); + assert_er_radix::("1", 16, ParseErrorKind::Overflow); assert_ok_radix::("7F.FF7", 16, 0x7FFF); assert_ok_radix::("7F.FF8", 16, 0x8000); assert_ok_radix::("FF.FF7", 16, 0xFFFF); - assert_err_radix::("FF.FF8", 16, ParseErrorKind::Overflow); + assert_er_radix::("FF.FF8", 16, ParseErrorKind::Overflow); assert_ok_radix::("7FFF.7", 16, 0x7FFF); assert_ok_radix::("7FFF.8", 16, 0x8000); assert_ok_radix::("FFFF.7", 16, 0xFFFF); - assert_err_radix::("FFFF.8", 16, ParseErrorKind::Overflow); + assert_er_radix::("FFFF.8", 16, ParseErrorKind::Overflow); } #[test] fn check_i64_u64_from_str() { - assert_err::("-1", ParseErrorKind::Overflow); - assert_err::("-0.50000000000000000003", ParseErrorKind::Overflow); + assert_er::("-1", ParseErrorKind::Overflow); + assert_er::("-0.50000000000000000003", ParseErrorKind::Overflow); assert_ok::("-0.50000000000000000002", -0x8000_0000_0000_0000); assert_ok::("0.49999999999999999997", 0x7FFF_FFFF_FFFF_FFFF); - assert_err::("0.49999999999999999998", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.49999999999999999998", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); - assert_err::("-2147483648.0000000002", ParseErrorKind::Overflow); + assert_er::("-2147483648.0000000002", ParseErrorKind::Overflow); assert_ok::("-2147483648.0000000001", -0x8000_0000_0000_0000); assert_ok::("2147483647.9999999998", 0x7FFF_FFFF_FFFF_FFFF); - assert_err::("2147483647.9999999999", ParseErrorKind::Overflow); + assert_er::("2147483647.9999999999", ParseErrorKind::Overflow); - assert_err::("-9223372036854775808.5", ParseErrorKind::Overflow); + assert_er::("-9223372036854775808.5", ParseErrorKind::Overflow); assert_ok::( "-9223372036854775808.49999999999999999999", -0x8000_0000_0000_0000, @@ -1182,19 +1195,19 @@ mod tests { "9223372036854775807.49999999999999999999", 0x7FFF_FFFF_FFFF_FFFF, ); - assert_err::("9223372036854775807.5", ParseErrorKind::Overflow); + assert_er::("9223372036854775807.5", ParseErrorKind::Overflow); - assert_err::("-0", ParseErrorKind::InvalidDigit); + assert_er::("-0", ParseErrorKind::InvalidDigit); assert_ok::("0.49999999999999999997", 0x7FFF_FFFF_FFFF_FFFF); assert_ok::("0.49999999999999999998", 0x8000_0000_0000_0000); assert_ok::("0.99999999999999999997", 0xFFFF_FFFF_FFFF_FFFF); - assert_err::("0.99999999999999999998", ParseErrorKind::Overflow); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("0.99999999999999999998", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); assert_ok::("2147483647.9999999998", 0x7FFF_FFFF_FFFF_FFFF); assert_ok::("2147483647.9999999999", 0x8000_0000_0000_0000); assert_ok::("4294967295.9999999998", 0xFFFF_FFFF_FFFF_FFFF); - assert_err::("4294967295.9999999999", ParseErrorKind::Overflow); + assert_er::("4294967295.9999999999", ParseErrorKind::Overflow); assert_ok::( "9223372036854775807.49999999999999999999", @@ -1205,13 +1218,13 @@ mod tests { "18446744073709551615.49999999999999999999", 0xFFFF_FFFF_FFFF_FFFF, ); - assert_err::("18446744073709551615.5", ParseErrorKind::Overflow); + assert_er::("18446744073709551615.5", ParseErrorKind::Overflow); } #[test] fn check_i128_u128_from_str() { - assert_err::("-1", ParseErrorKind::Overflow); - assert_err::( + assert_er::("-1", ParseErrorKind::Overflow); + assert_er::( "-0.500000000000000000000000000000000000002", ParseErrorKind::Overflow, ); @@ -1223,13 +1236,13 @@ mod tests { "0.499999999999999999999999999999999999998", 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err::( + assert_er::( "0.499999999999999999999999999999999999999", ParseErrorKind::Overflow, ); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); - assert_err::( + assert_er::( "-9223372036854775808.00000000000000000003", ParseErrorKind::Overflow, ); @@ -1241,12 +1254,12 @@ mod tests { "9223372036854775807.99999999999999999997", 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err::( + assert_er::( "9223372036854775807.99999999999999999998", ParseErrorKind::Overflow, ); - assert_err::( + assert_er::( "-170141183460469231731687303715884105728.5", ParseErrorKind::Overflow, ); @@ -1258,12 +1271,12 @@ mod tests { "170141183460469231731687303715884105727.4999999999999999999999999999999999999999", 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err::( + assert_er::( "170141183460469231731687303715884105727.5", ParseErrorKind::Overflow, ); - assert_err::("-0", ParseErrorKind::InvalidDigit); + assert_er::("-0", ParseErrorKind::InvalidDigit); assert_ok::( "0.499999999999999999999999999999999999998", 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, @@ -1276,11 +1289,11 @@ mod tests { "0.999999999999999999999999999999999999998", 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err::( + assert_er::( "0.999999999999999999999999999999999999999", ParseErrorKind::Overflow, ); - assert_err::("1", ParseErrorKind::Overflow); + assert_er::("1", ParseErrorKind::Overflow); assert_ok::( "9223372036854775807.99999999999999999997", @@ -1294,7 +1307,7 @@ mod tests { "18446744073709551615.99999999999999999997", 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err::( + assert_er::( "18446744073709551615.99999999999999999998", ParseErrorKind::Overflow, ); @@ -1311,7 +1324,7 @@ mod tests { "340282366920938463463374607431768211455.4999999999999999999999999999999999999999", 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err::( + assert_er::( "340282366920938463463374607431768211455.5", ParseErrorKind::Overflow, ); @@ -1319,72 +1332,87 @@ mod tests { #[test] fn check_i128_u128_from_str_hex() { - assert_err_radix::("-1", 16, ParseErrorKind::Overflow); - assert_err_radix::( + assert_er_radix::("-1", 16, ParseErrorKind::Overflow); + assert_er_radix::( + "-0.800000000000000000000000000000009", + 16, + ParseErrorKind::Overflow, + ); + assert_ok_radix::( "-0.800000000000000000000000000000008", 16, - ParseErrorKind::Overflow, + -0x8000_0000_0000_0000_0000_0000_0000_0000, ); assert_ok_radix::( - "-0.800000000000000000000000000000007", + "-0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8", 16, -0x8000_0000_0000_0000_0000_0000_0000_0000, ); assert_ok_radix::( - "0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7", + "+0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7", 16, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err_radix::( - "0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8", + assert_er_radix::( + "+0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8", 16, ParseErrorKind::Overflow, ); - assert_err_radix::("1", 16, ParseErrorKind::Overflow); + assert_er_radix::("1", 16, ParseErrorKind::Overflow); - assert_err_radix::( + assert_er_radix::( + "-8000000000000000.00000000000000009", + 16, + ParseErrorKind::Overflow, + ); + assert_ok_radix::( "-8000000000000000.00000000000000008", 16, - ParseErrorKind::Overflow, + -0x8000_0000_0000_0000_0000_0000_0000_0000, ); assert_ok_radix::( - "-8000000000000000.00000000000000007", + "-7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8", 16, -0x8000_0000_0000_0000_0000_0000_0000_0000, ); assert_ok_radix::( - "7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF7", + "+7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF7", 16, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err_radix::( - "7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8", + assert_er_radix::( + "+7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8", 16, ParseErrorKind::Overflow, ); - assert_err_radix::( + assert_er_radix::( + "-80000000000000000000000000000000.9", + 16, + ParseErrorKind::Overflow, + ); + assert_ok_radix::( "-80000000000000000000000000000000.8", 16, - ParseErrorKind::Overflow, + -0x8000_0000_0000_0000_0000_0000_0000_0000, ); assert_ok_radix::( - "-80000000000000000000000000000000.7", + "-7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8", 16, -0x8000_0000_0000_0000_0000_0000_0000_0000, ); assert_ok_radix::( - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.7", + "+7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.7", 16, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err_radix::( - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8", + assert_er_radix::( + "+7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8", 16, ParseErrorKind::Overflow, ); - assert_err_radix::("-0", 16, ParseErrorKind::InvalidDigit); + assert_er_radix::("-0", 16, ParseErrorKind::InvalidDigit); assert_ok_radix::( "0.7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7", 16, @@ -1400,12 +1428,12 @@ mod tests { 16, 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err_radix::( + assert_er_radix::( "0.FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8", 16, ParseErrorKind::Overflow, ); - assert_err_radix::("1", 16, ParseErrorKind::Overflow); + assert_er_radix::("1", 16, ParseErrorKind::Overflow); assert_ok_radix::( "7FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF7", @@ -1422,7 +1450,7 @@ mod tests { 16, 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err_radix::( + assert_er_radix::( "FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF8", 16, ParseErrorKind::Overflow, @@ -1443,7 +1471,7 @@ mod tests { 16, 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ); - assert_err_radix::( + assert_er_radix::( "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.8", 16, ParseErrorKind::Overflow, @@ -1521,78 +1549,78 @@ mod tests { assert_ok::(&frac_0_8.zero, 0); assert_ok::(&frac_0_8.eps, 1); assert_ok::(&frac_0_8.one_minus_eps, !0); - assert_err::(&frac_0_8.one, ParseErrorKind::Overflow); + assert_er::(&frac_0_8.one, ParseErrorKind::Overflow); let frac_4_4 = make_fraction_strings(&prefix4, eps4); assert_ok::(&frac_4_4.zero, 0); assert_ok::(&frac_4_4.eps, 1); assert_ok::(&frac_4_4.one_minus_eps, !0); - assert_err::(&frac_4_4.one, ParseErrorKind::Overflow); + assert_er::(&frac_4_4.one, ParseErrorKind::Overflow); let frac_8_0 = make_fraction_strings(&prefix8, eps0); assert_ok::(&frac_8_0.zero, 0); assert_ok::(&frac_8_0.eps, 1); assert_ok::(&frac_8_0.one_minus_eps, !0); - assert_err::(&frac_8_0.one, ParseErrorKind::Overflow); + assert_er::(&frac_8_0.one, ParseErrorKind::Overflow); let frac_0_32 = make_fraction_strings(&prefix0, eps32); assert_ok::(&frac_0_32.zero, 0); assert_ok::(&frac_0_32.eps, 1); assert_ok::(&frac_0_32.one_minus_eps, !0); - assert_err::(&frac_0_32.one, ParseErrorKind::Overflow); + assert_er::(&frac_0_32.one, ParseErrorKind::Overflow); let frac_4_28 = make_fraction_strings(&prefix4, eps28); assert_ok::(&frac_4_28.zero, 0); assert_ok::(&frac_4_28.eps, 1); assert_ok::(&frac_4_28.one_minus_eps, !0); - assert_err::(&frac_4_28.one, ParseErrorKind::Overflow); + assert_er::(&frac_4_28.one, ParseErrorKind::Overflow); let frac_16_16 = make_fraction_strings(&prefix16, eps16); assert_ok::(&frac_16_16.zero, 0); assert_ok::(&frac_16_16.eps, 1); assert_ok::(&frac_16_16.one_minus_eps, !0); - assert_err::(&frac_16_16.one, ParseErrorKind::Overflow); + assert_er::(&frac_16_16.one, ParseErrorKind::Overflow); let frac_28_4 = make_fraction_strings(&prefix28, eps4); assert_ok::(&frac_28_4.zero, 0); assert_ok::(&frac_28_4.eps, 1); assert_ok::(&frac_28_4.one_minus_eps, !0); - assert_err::(&frac_28_4.one, ParseErrorKind::Overflow); + assert_er::(&frac_28_4.one, ParseErrorKind::Overflow); let frac_32_0 = make_fraction_strings(&prefix32, eps0); assert_ok::(&frac_32_0.zero, 0); assert_ok::(&frac_32_0.eps, 1); assert_ok::(&frac_32_0.one_minus_eps, !0); - assert_err::(&frac_32_0.one, ParseErrorKind::Overflow); + assert_er::(&frac_32_0.one, ParseErrorKind::Overflow); let frac_0_128 = make_fraction_strings(&prefix0, eps128); assert_ok::(&frac_0_128.zero, 0); assert_ok::(&frac_0_128.eps, 1); assert_ok::(&frac_0_128.one_minus_eps, !0); - assert_err::(&frac_0_128.one, ParseErrorKind::Overflow); + assert_er::(&frac_0_128.one, ParseErrorKind::Overflow); let frac_4_124 = make_fraction_strings(&prefix4, eps124); assert_ok::(&frac_4_124.zero, 0); assert_ok::(&frac_4_124.eps, 1); assert_ok::(&frac_4_124.one_minus_eps, !0); - assert_err::(&frac_4_124.one, ParseErrorKind::Overflow); + assert_er::(&frac_4_124.one, ParseErrorKind::Overflow); let frac_64_64 = make_fraction_strings(&prefix64, eps64); assert_ok::(&frac_64_64.zero, 0); assert_ok::(&frac_64_64.eps, 1); assert_ok::(&frac_64_64.one_minus_eps, !0); - assert_err::(&frac_64_64.one, ParseErrorKind::Overflow); + assert_er::(&frac_64_64.one, ParseErrorKind::Overflow); let frac_124_4 = make_fraction_strings(&prefix124, eps4); assert_ok::(&frac_124_4.zero, 0); assert_ok::(&frac_124_4.eps, 1); assert_ok::(&frac_124_4.one_minus_eps, !0); - assert_err::(&frac_124_4.one, ParseErrorKind::Overflow); + assert_er::(&frac_124_4.one, ParseErrorKind::Overflow); let frac_128_0 = make_fraction_strings(&prefix128, eps0); assert_ok::(&frac_128_0.zero, 0); assert_ok::(&frac_128_0.eps, 1); assert_ok::(&frac_128_0.one_minus_eps, !0); - assert_err::(&frac_128_0.one, ParseErrorKind::Overflow); + assert_er::(&frac_128_0.one, ParseErrorKind::Overflow); } } diff --git a/src/int_helper.rs b/src/int_helper.rs index 5b1d550..5c771fb 100644 --- a/src/int_helper.rs +++ b/src/int_helper.rs @@ -42,6 +42,7 @@ where const ZERO: Self; fn is_negative(self) -> bool; + fn is_odd(self) -> bool; fn checked_add(self, val: Self) -> Option; fn checked_mul(self, val: Self) -> Option; fn overflowing_add(self, val: Self) -> (Self, bool); @@ -114,6 +115,11 @@ macro_rules! sealed_int { false } + #[inline] + fn is_odd(self) -> bool { + self & 1 != 0 + } + #[inline] fn neg_abs(self) -> (bool, Self::Unsigned) { (false, self) @@ -177,6 +183,11 @@ macro_rules! sealed_int { self < 0 } + #[inline] + fn is_odd(self) -> bool { + self & 1 != 0 + } + #[inline] fn neg_abs(self) -> (bool, Self::Unsigned) { if self < 0 {