Parse a float using the same format as `format_float` above. The encoding parameters are: w - exponent field width in bits t - trailing significand field width in bits
(s: &str, w: u8, t: u8)
| 969 | /// t - trailing significand field width in bits |
| 970 | /// |
| 971 | fn parse_float(s: &str, w: u8, t: u8) -> Result<u128, &'static str> { |
| 972 | debug_assert!(w > 0 && w <= 16, "Invalid exponent range"); |
| 973 | debug_assert!(1 + w + t <= 128, "Too large IEEE format for u128"); |
| 974 | debug_assert!((t + w + 1).is_power_of_two(), "Unexpected IEEE format size"); |
| 975 | |
| 976 | let (sign_bit, s2) = if let Some(num) = s.strip_prefix('-') { |
| 977 | (1u128 << (t + w), num) |
| 978 | } else if let Some(num) = s.strip_prefix('+') { |
| 979 | (0, num) |
| 980 | } else { |
| 981 | (0, s) |
| 982 | }; |
| 983 | |
| 984 | if !s2.starts_with("0x") { |
| 985 | let max_e_bits = ((1u128 << w) - 1) << t; |
| 986 | let quiet_bit = 1u128 << (t - 1); |
| 987 | |
| 988 | // The only decimal encoding allowed is 0. |
| 989 | if s2 == "0.0" { |
| 990 | return Ok(sign_bit); |
| 991 | } |
| 992 | |
| 993 | if s2 == "Inf" { |
| 994 | // +/- infinity: e = max, t = 0. |
| 995 | return Ok(sign_bit | max_e_bits); |
| 996 | } |
| 997 | if s2 == "NaN" { |
| 998 | // Canonical quiet NaN: e = max, t = quiet. |
| 999 | return Ok(sign_bit | max_e_bits | quiet_bit); |
| 1000 | } |
| 1001 | if let Some(nan) = s2.strip_prefix("NaN:0x") { |
| 1002 | // Quiet NaN with payload. |
| 1003 | return match u128::from_str_radix(nan, 16) { |
| 1004 | Ok(payload) if payload < quiet_bit => { |
| 1005 | Ok(sign_bit | max_e_bits | quiet_bit | payload) |
| 1006 | } |
| 1007 | _ => Err("Invalid NaN payload"), |
| 1008 | }; |
| 1009 | } |
| 1010 | if let Some(nan) = s2.strip_prefix("sNaN:0x") { |
| 1011 | // Signaling NaN with payload. |
| 1012 | return match u128::from_str_radix(nan, 16) { |
| 1013 | Ok(payload) if 0 < payload && payload < quiet_bit => { |
| 1014 | Ok(sign_bit | max_e_bits | payload) |
| 1015 | } |
| 1016 | _ => Err("Invalid sNaN payload"), |
| 1017 | }; |
| 1018 | } |
| 1019 | |
| 1020 | return Err("Float must be hexadecimal"); |
| 1021 | } |
| 1022 | let s3 = &s2[2..]; |
| 1023 | |
| 1024 | let mut digits = 0u8; |
| 1025 | let mut digits_before_period: Option<u8> = None; |
| 1026 | let mut significand = 0u128; |
| 1027 | let mut exponent = 0i32; |
| 1028 |
nothing calls this directly
no test coverage detected