use lib::slice;
use super::algorithm::copy_to_dst;
use super::rounding::RoundingKind;
pub(crate) struct FloatConfigString {
data: [u8; MAX_F32_SIZE - 1],
length: usize,
}
impl FloatConfigString {
pub(crate) fn load_bytes(&mut self, bytes: &[u8]) {
assert!(bytes.len() <= self.data.len());
copy_to_dst(&mut self.data, bytes);
self.length = bytes.len();
}
pub(crate) fn as_bytes(&self) -> &[u8] {
unsafe {
self.data.get_unchecked(..self.length)
}
}
}
cfg_if! {
if #[cfg(feature = "radix")] {
static mut NAN_STRING: FloatConfigString = FloatConfigString {
data: [b'N', b'a', b'N', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'],
length: 3
};
static mut INF_STRING: FloatConfigString = FloatConfigString {
data: [b'i', b'n', b'f', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'],
length: 3
};
static mut INFINITY_STRING: FloatConfigString = FloatConfigString {
data: [b'i', b'n', b'f', b'i', b'n', b'i', b't', b'y', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'],
length: 8
};
} else {
static mut NAN_STRING: FloatConfigString = FloatConfigString {
data: [b'N', b'a', b'N', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'],
length: 3
};
static mut INF_STRING: FloatConfigString = FloatConfigString {
data: [b'i', b'n', b'f', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'],
length: 3
};
static mut INFINITY_STRING: FloatConfigString = FloatConfigString {
data: [b'i', b'n', b'f', b'i', b'n', b'i', b't', b'y', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'],
length: 8
};
}}
#[no_mangle]
pub static mut EXPONENT_DEFAULT_CHAR: u8 = b'e';
#[cfg(feature ="radix")]
#[no_mangle]
pub static mut EXPONENT_BACKUP_CHAR: u8 = b'^';
#[inline]
unsafe extern fn get_string_ffi(ptr: *mut *const u8, size: *mut usize, string: &'static FloatConfigString)
-> i32
{
if ptr.is_null() || size.is_null() {
-1
} else {
let slc = string.as_bytes();
*ptr = slc.as_ptr();
*size = slc.len();
0
}
}
#[inline]
unsafe extern fn set_string_ffi(ptr: *const u8, size: usize, string: &'static mut FloatConfigString)
-> i32
{
if ptr.is_null() {
-1
} else {
string.load_bytes(slice::from_raw_parts(ptr, size));
0
}
}
#[inline]
pub fn get_nan_string() -> &'static [u8]
{
unsafe {
NAN_STRING.as_bytes()
}
}
#[no_mangle]
pub unsafe extern fn get_nan_string_ffi(ptr: *mut *const u8, size: *mut usize)
-> i32
{
get_string_ffi(ptr, size, &NAN_STRING)
}
#[inline]
pub unsafe fn set_nan_string(bytes: &[u8])
{
NAN_STRING.load_bytes(bytes);
}
#[no_mangle]
pub unsafe extern fn set_nan_string_ffi(ptr: *const u8, size: usize)
-> i32
{
set_string_ffi(ptr, size, &mut NAN_STRING)
}
#[inline]
pub fn get_inf_string() -> &'static [u8]
{
unsafe {
INF_STRING.as_bytes()
}
}
#[no_mangle]
pub unsafe extern fn get_inf_string_ffi(ptr: *mut *const u8, size: *mut usize)
-> i32
{
get_string_ffi(ptr, size, &mut INF_STRING)
}
#[inline]
pub unsafe fn set_inf_string(bytes: &[u8])
{
INF_STRING.load_bytes(bytes);
}
#[no_mangle]
pub unsafe extern fn set_inf_string_ffi(ptr: *const u8, size: usize)
-> i32
{
set_string_ffi(ptr, size, &mut INF_STRING)
}
#[inline]
pub fn get_infinity_string() -> &'static [u8]
{
unsafe {
INFINITY_STRING.as_bytes()
}
}
#[no_mangle]
pub unsafe extern fn get_infinity_string_ffi(ptr: *mut *const u8, size: *mut usize)
-> i32
{
get_string_ffi(ptr, size, &mut INFINITY_STRING)
}
#[inline]
pub unsafe fn set_infinity_string(bytes: &[u8])
{
INFINITY_STRING.load_bytes(bytes);
}
#[no_mangle]
pub unsafe extern fn set_infinity_string_ffi(ptr: *const u8, size: usize)
-> i32
{
set_string_ffi(ptr, size, &mut INFINITY_STRING)
}
cfg_if! {
if #[cfg(feature = "radix")] {
pub const MAX_I8_SIZE: usize = 16;
pub const MAX_I16_SIZE: usize = 32;
pub const MAX_I32_SIZE: usize = 64;
pub const MAX_I64_SIZE: usize = 128;
pub const MAX_I128_SIZE: usize = 256;
pub const MAX_U8_SIZE: usize = 16;
pub const MAX_U16_SIZE: usize = 32;
pub const MAX_U32_SIZE: usize = 64;
pub const MAX_U64_SIZE: usize = 128;
pub const MAX_U128_SIZE: usize = 256;
pub const MAX_F32_SIZE: usize = 256;
pub const MAX_F64_SIZE: usize = 256;
} else {
pub const MAX_I8_SIZE: usize = 4;
pub const MAX_I16_SIZE: usize = 6;
pub const MAX_I32_SIZE: usize = 11;
pub const MAX_I64_SIZE: usize = 20;
pub const MAX_I128_SIZE: usize = 40;
pub const MAX_U8_SIZE: usize = 3;
pub const MAX_U16_SIZE: usize = 5;
pub const MAX_U32_SIZE: usize = 10;
pub const MAX_U64_SIZE: usize = 20;
pub const MAX_U128_SIZE: usize = 39;
pub const MAX_F32_SIZE: usize = 64;
pub const MAX_F64_SIZE: usize = 64;
}}
cfg_if! {
if #[cfg(target_pointer_width = "16")] {
pub const MAX_ISIZE_SIZE: usize = MAX_I16_SIZE;
pub const MAX_USIZE_SIZE: usize = MAX_U16_SIZE;
} else if #[cfg(target_pointer_width = "32")] {
pub const MAX_ISIZE_SIZE: usize = MAX_I32_SIZE;
pub const MAX_USIZE_SIZE: usize = MAX_U32_SIZE;
} else if #[cfg(target_pointer_width = "64")] {
pub const MAX_ISIZE_SIZE: usize = MAX_I64_SIZE;
pub const MAX_USIZE_SIZE: usize = MAX_U64_SIZE;
}}
pub const BUFFER_SIZE: usize = MAX_F64_SIZE;
#[no_mangle]
pub static MAX_I8_SIZE_FFI: usize = MAX_I8_SIZE;
#[no_mangle]
pub static MAX_I16_SIZE_FFI: usize = MAX_I16_SIZE;
#[no_mangle]
pub static MAX_I32_SIZE_FFI: usize = MAX_I32_SIZE;
#[no_mangle]
pub static MAX_I64_SIZE_FFI: usize = MAX_I64_SIZE;
#[no_mangle]
pub static MAX_I128_SIZE_FFI: usize = MAX_I128_SIZE;
#[no_mangle]
pub static MAX_ISIZE_SIZE_FFI: usize = MAX_ISIZE_SIZE;
#[no_mangle]
pub static MAX_U8_SIZE_FFI: usize = MAX_U8_SIZE;
#[no_mangle]
pub static MAX_U16_SIZE_FFI: usize = MAX_U16_SIZE;
#[no_mangle]
pub static MAX_U32_SIZE_FFI: usize = MAX_U32_SIZE;
#[no_mangle]
pub static MAX_U64_SIZE_FFI: usize = MAX_U64_SIZE;
#[no_mangle]
pub static MAX_U128_SIZE_FFI: usize = MAX_U128_SIZE;
#[no_mangle]
pub static MAX_USIZE_SIZE_FFI: usize = MAX_USIZE_SIZE;
#[no_mangle]
pub static MAX_F32_SIZE_FFI: usize = MAX_F32_SIZE;
#[no_mangle]
pub static MAX_F64_SIZE_FFI: usize = MAX_F64_SIZE;
#[no_mangle]
pub static BUFFER_SIZE_FFI: usize = BUFFER_SIZE;
#[no_mangle]
#[cfg(feature = "rounding")]
pub static mut FLOAT_ROUNDING: RoundingKind = RoundingKind::NearestTieEven;
#[inline]
#[allow(unused_variables)]
pub(crate) fn exponent_notation_char(radix: u32) -> u8 {
unsafe {
#[cfg(not(feature ="radix"))] {
EXPONENT_DEFAULT_CHAR
}
#[cfg(feature ="radix")] {
if radix >= 15 { EXPONENT_BACKUP_CHAR } else { EXPONENT_DEFAULT_CHAR }
}
}
}
#[cfg(test)]
mod tests {
use atof::*;
use ftoa::*;
use util::*;
use util::test::*;
use super::*;
#[cfg(feature ="radix")]
#[test]
fn exponent_notation_char_test() {
unsafe {
assert_eq!(exponent_notation_char(2), EXPONENT_DEFAULT_CHAR);
assert_eq!(exponent_notation_char(8), EXPONENT_DEFAULT_CHAR);
assert_eq!(exponent_notation_char(10), EXPONENT_DEFAULT_CHAR);
assert_eq!(exponent_notation_char(15), EXPONENT_BACKUP_CHAR);
assert_eq!(exponent_notation_char(16), EXPONENT_BACKUP_CHAR);
assert_eq!(exponent_notation_char(32), EXPONENT_BACKUP_CHAR);
}
}
#[test]
#[ignore]
fn special_bytes_test() {
unsafe {
let mut buffer = new_buffer();
assert!(try_atof32_slice(b"NaN").value.is_nan());
assert!(try_atof32_slice(b"nan").value.is_nan());
assert!(try_atof32_slice(b"NAN").value.is_nan());
assert!(try_atof32_slice(b"inf").value.is_infinite());
assert!(try_atof32_slice(b"INF").value.is_infinite());
assert!(try_atof32_slice(b"Infinity").value.is_infinite());
assert_eq!(f64toa_slice(f64::NAN, &mut buffer), b"NaN");
assert_eq!(f64toa_slice(f64::INFINITY, &mut buffer), b"inf");
NAN_STRING.load_bytes(b"nan");
INF_STRING.load_bytes(b"Infinity");
assert!(try_atof32_slice(b"inf").error.code == ErrorCode::InvalidDigit);
assert!(try_atof32_slice(b"Infinity").value.is_infinite());
assert_eq!(f64toa_slice(f64::NAN, &mut buffer), b"nan");
assert_eq!(f64toa_slice(f64::INFINITY, &mut buffer), b"Infinity");
NAN_STRING.load_bytes(b"NaN");
INF_STRING.load_bytes(b"inf");
}
}
#[cfg(all(feature = "correct", feature = "rounding"))]
#[test]
#[ignore]
fn special_rounding_test() {
unsafe {
FLOAT_ROUNDING = RoundingKind::NearestTieEven;
assert_eq!(try_atof64_slice(b"-9007199254740993").value, -9007199254740992.0);
assert_eq!(try_atof64_slice(b"-9007199254740995").value, -9007199254740996.0);
assert_eq!(try_atof64_slice(b"9007199254740993").value, 9007199254740992.0);
assert_eq!(try_atof64_slice(b"9007199254740995").value, 9007199254740996.0);
FLOAT_ROUNDING = RoundingKind::NearestTieAwayZero;
assert_eq!(try_atof64_slice(b"-9007199254740993").value, -9007199254740994.0);
assert_eq!(try_atof64_slice(b"-9007199254740995").value, -9007199254740996.0);
assert_eq!(try_atof64_slice(b"9007199254740993").value, 9007199254740994.0);
assert_eq!(try_atof64_slice(b"9007199254740995").value, 9007199254740996.0);
FLOAT_ROUNDING = RoundingKind::TowardPositiveInfinity;
assert_eq!(try_atof64_slice(b"-9007199254740993").value, -9007199254740992.0);
assert_eq!(try_atof64_slice(b"-9007199254740995").value, -9007199254740994.0);
assert_eq!(try_atof64_slice(b"9007199254740993").value, 9007199254740994.0);
assert_eq!(try_atof64_slice(b"9007199254740995").value, 9007199254740996.0);
FLOAT_ROUNDING = RoundingKind::TowardNegativeInfinity;
assert_eq!(try_atof64_slice(b"-9007199254740993").value, -9007199254740994.0);
assert_eq!(try_atof64_slice(b"-9007199254740995").value, -9007199254740996.0);
assert_eq!(try_atof64_slice(b"9007199254740993").value, 9007199254740992.0);
assert_eq!(try_atof64_slice(b"9007199254740995").value, 9007199254740994.0);
FLOAT_ROUNDING = RoundingKind::TowardZero;
assert_eq!(try_atof64_slice(b"-9007199254740993").value, -9007199254740992.0);
assert_eq!(try_atof64_slice(b"-9007199254740995").value, -9007199254740994.0);
assert_eq!(try_atof64_slice(b"9007199254740993").value, 9007199254740992.0);
assert_eq!(try_atof64_slice(b"9007199254740995").value, 9007199254740994.0);
FLOAT_ROUNDING = RoundingKind::NearestTieEven;
}
}
#[cfg(all(feature = "correct", feature = "radix", feature = "rounding"))]
#[test]
#[ignore]
fn special_rounding_binary_test() {
unsafe {
FLOAT_ROUNDING = RoundingKind::NearestTieEven;
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000001").value, -9007199254740992.0);
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000011").value, -9007199254740996.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000001").value, 9007199254740992.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000011").value, 9007199254740996.0);
FLOAT_ROUNDING = RoundingKind::NearestTieAwayZero;
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000001").value, -9007199254740994.0);
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000011").value, -9007199254740996.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000001").value, 9007199254740994.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000011").value, 9007199254740996.0);
FLOAT_ROUNDING = RoundingKind::TowardPositiveInfinity;
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000001").value, -9007199254740992.0);
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000011").value, -9007199254740994.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000001").value, 9007199254740994.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000011").value, 9007199254740996.0);
FLOAT_ROUNDING = RoundingKind::TowardNegativeInfinity;
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000001").value, -9007199254740994.0);
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000011").value, -9007199254740996.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000001").value, 9007199254740992.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000011").value, 9007199254740994.0);
FLOAT_ROUNDING = RoundingKind::TowardZero;
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000001").value, -9007199254740992.0);
assert_eq!(try_atof64_radix_slice(2, b"-100000000000000000000000000000000000000000000000000011").value, -9007199254740994.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000001").value, 9007199254740992.0);
assert_eq!(try_atof64_radix_slice(2, b"100000000000000000000000000000000000000000000000000011").value, 9007199254740994.0);
FLOAT_ROUNDING = RoundingKind::NearestTieEven;
}
}
}