#[cfg(feature = "format")]
use core::num;
use lexical_parse_float::{FromLexical, FromLexicalWithOptions, Options};
use lexical_util::error::Error;
#[cfg(feature = "format")]
use lexical_util::format;
#[cfg(any(feature = "format", feature = "power-of-two"))]
use lexical_util::format::NumberFormatBuilder;
use lexical_util::format::STANDARD;
#[test]
fn special_bytes_test() {
const FORMAT: u128 = STANDARD;
// Test serializing and deserializing special strings.
assert!(f32::from_lexical(b"NaN").unwrap().is_nan());
assert!(f32::from_lexical(b"nan").unwrap().is_nan());
assert!(f32::from_lexical(b"NAN").unwrap().is_nan());
assert!(f32::from_lexical(b"inf").unwrap().is_infinite());
assert!(f32::from_lexical(b"INF").unwrap().is_infinite());
assert!(f32::from_lexical(b"Infinity").unwrap().is_infinite());
const OPTIONS: Options =
Options::builder().nan_string(Some(b"nan")).inf_string(Some(b"Infinity")).build_strict();
// The error message depends on whether the radix feature is enabled.
assert!(f32::from_lexical_with_options::<FORMAT>(b"inf", &OPTIONS).is_err());
assert!(f32::from_lexical_with_options::<FORMAT>(b"Infinity", &OPTIONS).unwrap().is_infinite());
}
#[test]
#[cfg(feature = "power-of-two")]
fn invalid_format_test() {
const FORMAT: u128 = NumberFormatBuilder::from_radix(40);
const OPTIONS: Options = Options::new();
let res = f32::from_lexical_with_options::<FORMAT>(b"inf", &OPTIONS);
assert!(res.is_err());
assert_eq!(res, Err(Error::InvalidMantissaRadix));
}
#[test]
#[cfg(all(feature = "power-of-two", feature = "format"))]
fn invalid_punctuation_test() {
const FORMAT: u128 = NumberFormatBuilder::new()
.digit_separator(num::NonZeroU8::new(b'h'))
.base_prefix(num::NonZeroU8::new(b'h'))
.integer_internal_digit_separator(true)
.build_unchecked();
const OPTIONS: Options = Options::new();
let res = f32::from_lexical_with_options::<FORMAT>(b"inf", &OPTIONS);
assert!(res.is_err());
assert_eq!(res, Err(Error::InvalidPunctuation));
}
#[test]
fn f32_decimal_test() {
// integer test
assert_eq!(0.0, f32::from_lexical(b"0").unwrap());
assert_eq!(1.0, f32::from_lexical(b"1").unwrap());
assert_eq!(12.0, f32::from_lexical(b"12").unwrap());
assert_eq!(123.0, f32::from_lexical(b"123").unwrap());
assert_eq!(1234.0, f32::from_lexical(b"1234").unwrap());
assert_eq!(12345.0, f32::from_lexical(b"12345").unwrap());
assert_eq!(123456.0, f32::from_lexical(b"123456").unwrap());
assert_eq!(1234567.0, f32::from_lexical(b"1234567").unwrap());
assert_eq!(12345678.0, f32::from_lexical(b"12345678").unwrap());
// No fraction after decimal point test
assert_eq!(1.0, f32::from_lexical(b"1.").unwrap());
assert_eq!(12.0, f32::from_lexical(b"12.").unwrap());
assert_eq!(1234567.0, f32::from_lexical(b"1234567.").unwrap());
// No integer before decimal point test
assert_eq!(0.1, f32::from_lexical(b".1").unwrap());
assert_eq!(0.12, f32::from_lexical(b".12").unwrap());
assert_eq!(0.1234567, f32::from_lexical(b".1234567").unwrap());
// decimal test
assert_eq!(123.1, f32::from_lexical(b"123.1").unwrap());
assert_eq!(123.12, f32::from_lexical(b"123.12").unwrap());
assert_eq!(123.123, f32::from_lexical(b"123.123").unwrap());
assert_eq!(123.1234, f32::from_lexical(b"123.1234").unwrap());
assert_eq!(123.12345, f32::from_lexical(b"123.12345").unwrap());
// rounding test
assert_eq!(123456790.0, f32::from_lexical(b"123456789").unwrap());
assert_eq!(123456790.0, f32::from_lexical(b"123456789.1").unwrap());
assert_eq!(123456790.0, f32::from_lexical(b"123456789.12").unwrap());
assert_eq!(123456790.0, f32::from_lexical(b"123456789.123").unwrap());
assert_eq!(123456790.0, f32::from_lexical(b"123456789.1234").unwrap());
assert_eq!(123456790.0, f32::from_lexical(b"123456789.12345").unwrap());
// exponent test
assert_eq!(123456789.12345, f32::from_lexical(b"1.2345678912345e8").unwrap());
assert_eq!(123450000.0, f32::from_lexical(b"1.2345e+8").unwrap());
assert_eq!(1.2345e+11, f32::from_lexical(b"1.2345e+11").unwrap());
assert_eq!(1.2345e+11, f32::from_lexical(b"123450000000").unwrap());
assert_eq!(1.2345e+38, f32::from_lexical(b"1.2345e+38").unwrap());
assert_eq!(1.2345e+38, f32::from_lexical(b"123450000000000000000000000000000000000").unwrap());
assert_eq!(1.2345e-8, f32::from_lexical(b"1.2345e-8").unwrap());
assert_eq!(1.2345e-8, f32::from_lexical(b"0.000000012345").unwrap());
assert_eq!(1.2345e-38, f32::from_lexical(b"1.2345e-38").unwrap());
assert_eq!(
1.2345e-38,
f32::from_lexical(b"0.000000000000000000000000000000000000012345").unwrap()
);
assert!(f32::from_lexical(b"NaN").unwrap().is_nan());
assert!(f32::from_lexical(b"nan").unwrap().is_nan());
assert!(f32::from_lexical(b"NAN").unwrap().is_nan());
assert!(f32::from_lexical(b"inf").unwrap().is_infinite());
assert!(f32::from_lexical(b"INF").unwrap().is_infinite());
assert!(f32::from_lexical(b"+inf").unwrap().is_infinite());
assert!(f32::from_lexical(b"-inf").unwrap().is_infinite());
// Check various expected failures.
assert_eq!(Err(Error::Empty(0)), f32::from_lexical(b""));
assert_eq!(Err(Error::EmptyMantissa(0)), f32::from_lexical(b"e"));
assert_eq!(Err(Error::EmptyMantissa(0)), f32::from_lexical(b"E"));
assert_eq!(Err(Error::EmptyMantissa(1)), f32::from_lexical(b".e1"));
assert_eq!(Err(Error::EmptyMantissa(1)), f32::from_lexical(b".e-1"));
assert_eq!(Err(Error::EmptyMantissa(0)), f32::from_lexical(b"e1"));
assert_eq!(Err(Error::EmptyMantissa(0)), f32::from_lexical(b"e-1"));
assert_eq!(Err(Error::Empty(1)), f32::from_lexical(b"+"));
assert_eq!(Err(Error::Empty(1)), f32::from_lexical(b"-"));
// Bug fix for Issue #8
assert_eq!(Ok(5.002868148396374), f32::from_lexical(b"5.002868148396374"));
// Other bug fixes
assert_eq!(Ok(7.2625224e+37), f32::from_lexical(b"72625224000000000000000000000000000000"));
assert_eq!(Ok(7.2625224e+37), f32::from_lexical(b"72625224000000000000000000000000000000.0"));
assert_eq!(Ok(-7.2625224e+37), f32::from_lexical(b"-72625224000000000000000000000000000000"));
assert_eq!(Ok(-7.2625224e+37), f32::from_lexical(b"-72625224000000000000000000000000000000.0"));
}
#[test]
#[cfg(feature = "radix")]
fn f32_radix_test() {
const BASE36: u128 = NumberFormatBuilder::from_radix(36);
const CUSTOM: Options = Options::builder().exponent(b'^').build_strict();
assert_eq!(1234.0, f32::from_lexical_with_options::<BASE36>(b"YA", &CUSTOM).unwrap());
const OPTIONS: Options = CUSTOM.rebuild().lossy(true).build_strict();
assert_eq!(1234.0, f32::from_lexical_with_options::<BASE36>(b"YA", &OPTIONS).unwrap());
const BASE21: u128 = NumberFormatBuilder::from_radix(21);
assert_eq!(
2879628700000000000000000.0,
f32::from_lexical_with_options::<BASE21>(b"4.BHJ97^I", &OPTIONS).unwrap()
);
assert_eq!(
48205230000000000000000000000000000000.0,
f32::from_lexical_with_options::<BASE21>(b"4.C4407^17", &OPTIONS).unwrap()
);
assert_eq!(
105861930000000000000000000000000000000.0,
f32::from_lexical_with_options::<BASE21>(b"A.15A^17", &OPTIONS).unwrap()
);
assert_eq!(
63900540000000000000000000000000000000.0,
f32::from_lexical_with_options::<BASE21>(b"6.1AK^17", &OPTIONS).unwrap()
);
assert_eq!(
48205210000000000000000000000000000000.0,
f32::from_lexical_with_options::<BASE21>(b"4.C44^17", &OPTIONS).unwrap()
);
assert_eq!(
48205230000000000000000000000000000000.0,
f32::from_lexical_with_options::<BASE21>(b"4C440700000000000000000000000.0", &OPTIONS)
.unwrap()
);
}
#[test]
fn parse_f32_test() {
let parse = move |x| f32::from_lexical_partial(x);
assert_eq!(Ok((0.0, 1)), parse(b"0"));
assert_eq!(Ok((1.2345, 6)), parse(b"1.2345"));
assert_eq!(Ok((12.345, 6)), parse(b"12.345"));
assert_eq!(Ok((12345.6789, 10)), parse(b"12345.6789"));
assert_eq!(Ok((1.2345e10, 9)), parse(b"1.2345e10"));
assert_eq!(Ok((1.2345e-38, 10)), parse(b"1.2345e-38"));
// Check expected rounding, using borderline cases.
// Round-down, halfway
assert_eq!(Ok((16777216.0, 8)), parse(b"16777216"));
assert_eq!(Ok((16777216.0, 8)), parse(b"16777217"));
assert_eq!(Ok((16777218.0, 8)), parse(b"16777218"));
assert_eq!(Ok((33554432.0, 8)), parse(b"33554432"));
assert_eq!(Ok((33554432.0, 8)), parse(b"33554434"));
assert_eq!(Ok((33554436.0, 8)), parse(b"33554436"));
assert_eq!(Ok((17179869184.0, 11)), parse(b"17179869184"));
assert_eq!(Ok((17179869184.0, 11)), parse(b"17179870208"));
assert_eq!(Ok((17179871232.0, 11)), parse(b"17179871232"));
// Round-up, halfway
assert_eq!(Ok((16777218.0, 8)), parse(b"16777218"));
assert_eq!(Ok((16777220.0, 8)), parse(b"16777219"));
assert_eq!(Ok((16777220.0, 8)), parse(b"16777220"));
assert_eq!(Ok((33554436.0, 8)), parse(b"33554436"));
assert_eq!(Ok((33554440.0, 8)), parse(b"33554438"));
assert_eq!(Ok((33554440.0, 8)), parse(b"33554440"));
assert_eq!(Ok((17179871232.0, 11)), parse(b"17179871232"));
assert_eq!(Ok((17179873280.0, 11)), parse(b"17179872256"));
assert_eq!(Ok((17179873280.0, 11)), parse(b"17179873280"));
// Round-up, above halfway
assert_eq!(Ok((33554436.0, 8)), parse(b"33554435"));
assert_eq!(Ok((17179871232.0, 11)), parse(b"17179870209"));
// Check exactly halfway, round-up at halfway
assert_eq!(Ok((1.0000001, 28)), parse(b"1.00000017881393432617187499"));
assert_eq!(Ok((1.0000002, 26)), parse(b"1.000000178813934326171875"));
assert_eq!(Ok((1.0000002, 28)), parse(b"1.00000017881393432617187501"));
// Invalid or partially-parsed
assert_eq!(Err(Error::EmptyMantissa(0)), parse(b"e10"));
assert_eq!(Err(Error::EmptyMantissa(1)), parse(b"."));
assert_eq!(Err(Error::EmptyMantissa(1)), parse(b".e10"));
assert_eq!(Err(Error::EmptyExponent(2)), parse(b"0e"));
assert_eq!(Ok((1.23, 4)), parse(b"1.23/"));
// Errors identified via test-parse-random.
assert_eq!(Ok((0.0, 21)), parse(b"1.565385248817619e-82"));
assert_eq!(Ok((5.483634359675252e34, 20)), parse(b"5.483634359675252e34"));
// Test a case from fast_float basictest.
assert_eq!(Ok((1.1754941e-38, 1118)), parse(b"1.17549414062751785924617589866280818433124586473279624003138594271817467598606476997247227700427174568176269531250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-38"));
assert_eq!(Ok((f32::INFINITY, 6)), parse(b"1e1000"));
// Errors identified via test-parse-golang.
assert_eq!(Ok((0, 25)), parse(b"1.00000000001e-2147483638").map(|(x, y)| (x.to_bits(), y)));
}
#[test]
fn parse_f64_test() {
let parse = move |x| f64::from_lexical_partial(x);
#[cfg(feature = "power-of-two")]
let parse_binary = move |x| {
const BINARY: u128 = NumberFormatBuilder::from_radix(2);
const OPTIONS: Options = Options::builder().exponent(b'^').build_strict();
f64::from_lexical_partial_with_options::<BINARY>(x, &OPTIONS)
};
assert_eq!(Ok((0.0, 1)), parse(b"0"));
assert_eq!(Ok((1.2345, 6)), parse(b"1.2345"));
assert_eq!(Ok((12.345, 6)), parse(b"12.345"));
assert_eq!(Ok((12345.6789, 10)), parse(b"12345.6789"));
assert_eq!(Ok((1.2345e10, 9)), parse(b"1.2345e10"));
assert_eq!(Ok((1e-323, 6)), parse(b"1e-323"));
assert_eq!(Ok((1.2345e-308, 11)), parse(b"1.2345e-308"));
// Check expected rounding, using borderline cases.
// Round-down, halfway
assert_eq!(Ok((9007199254740992.0, 16)), parse(b"9007199254740992"));
assert_eq!(Ok((9007199254740992.0, 16)), parse(b"9007199254740993"));
assert_eq!(Ok((9007199254740994.0, 16)), parse(b"9007199254740994"));
assert_eq!(Ok((18014398509481984.0, 17)), parse(b"18014398509481984"));
assert_eq!(Ok((18014398509481984.0, 17)), parse(b"18014398509481986"));
assert_eq!(Ok((18014398509481988.0, 17)), parse(b"18014398509481988"));
assert_eq!(Ok((9223372036854775808.0, 19)), parse(b"9223372036854775808"));
assert_eq!(Ok((9223372036854775808.0, 19)), parse(b"9223372036854776832"));
assert_eq!(Ok((9223372036854777856.0, 19)), parse(b"9223372036854777856"));
assert_eq!(
Ok((11417981541647679048466287755595961091061972992.0, 47)),
parse(b"11417981541647679048466287755595961091061972992")
);
assert_eq!(
Ok((11417981541647679048466287755595961091061972992.0, 47)),
parse(b"11417981541647680316116887983825362587765178368")
);
assert_eq!(
Ok((11417981541647681583767488212054764084468383744.0, 47)),
parse(b"11417981541647681583767488212054764084468383744")
);
// Round-up, halfway
assert_eq!(Ok((9007199254740994.0, 16)), parse(b"9007199254740994"));
assert_eq!(Ok((9007199254740996.0, 16)), parse(b"9007199254740995"));
assert_eq!(Ok((9007199254740996.0, 16)), parse(b"9007199254740996"));
assert_eq!(Ok((18014398509481988.0, 17)), parse(b"18014398509481988"));
assert_eq!(Ok((18014398509481992.0, 17)), parse(b"18014398509481990"));
assert_eq!(Ok((18014398509481992.0, 17)), parse(b"18014398509481992"));
assert_eq!(Ok((9223372036854777856.0, 19)), parse(b"9223372036854777856"));
assert_eq!(Ok((9223372036854779904.0, 19)), parse(b"9223372036854778880"));
assert_eq!(Ok((9223372036854779904.0, 19)), parse(b"9223372036854779904"));
assert_eq!(
Ok((11417981541647681583767488212054764084468383744.0, 47)),
parse(b"11417981541647681583767488212054764084468383744")
);
assert_eq!(
Ok((11417981541647684119068688668513567077874794496.0, 47)),
parse(b"11417981541647682851418088440284165581171589120")
);
assert_eq!(
Ok((11417981541647684119068688668513567077874794496.0, 47)),
parse(b"11417981541647684119068688668513567077874794496")
);
// Round-up, above halfway
assert_eq!(Ok((9223372036854777856.0, 19)), parse(b"9223372036854776833"));
assert_eq!(
Ok((11417981541647681583767488212054764084468383744.0, 47)),
parse(b"11417981541647680316116887983825362587765178369")
);
// Rounding error
// Adapted from failures in strtod.
assert_eq!(Ok((2.2250738585072014e-308, 23)), parse(b"2.2250738585072014e-308"));
assert_eq!(Ok((2.225073858507201e-308, 776)), parse(b"2.2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187499e-308"));
assert_eq!(Ok((2.2250738585072014e-308, 774)), parse(b"2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875e-308"));
assert_eq!(Ok((2.2250738585072014e-308, 776)), parse(b"2.2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187501e-308"));
assert_eq!(Ok((1.7976931348623157e+308, 380)), parse(b"179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999"));
assert_eq!(Ok((5e-324, 761)), parse(b"7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999e-324"));
assert_eq!(Ok((1e-323, 758)), parse(b"7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375e-324"));
assert_eq!(Ok((1e-323, 761)), parse(b"7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001e-324"));
assert_eq!(Ok((1e-320, 6)), parse(b"1e-320"));
// Highest denormal float.
assert_eq!(Ok((2.2250738585072009e-308, 23)), parse(b"2.2250738585072009e-308"));
// Rounding error
// Adapted from:
// https://www.exploringbinary.com/glibc-strtod-incorrectly-converts-2-to-the-negative-1075/
#[cfg(feature = "power-of-two")]
assert_eq!(Ok((5e-324, 14)), parse_binary(b"1^-10000110010"));
#[cfg(feature = "power-of-two")]
assert_eq!(Ok((0.0, 14)), parse_binary(b"1^-10000110011"));
assert_eq!(Ok((0.0, 1077)), parse(b"0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125"));
assert_eq!(Ok((5e-324, 1081)), parse(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210285131854513962138377228261454376934125320985913276672363281250001"));
assert_eq!(Ok((5e-324, 1078)), parse(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210285131854513962138377228261454376934125320985913276672363281251"));
// Check with trailing zeros too, before the max number.
assert_eq!(Ok((0.0, 1024)), parse(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210200000000"));
assert_eq!(Ok((5e-324, 1024)), parse(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210300000000"));
assert_eq!(Ok((5e-324, 1024)), parse(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210310000000"));
assert_eq!(Ok((0.0, 705)), parse(b"2.47032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210200000000e-324"));
assert_eq!(Ok((5e-324, 705)), parse(b"2.47032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210300000000e-324"));
assert_eq!(Ok((5e-324, 705)), parse(b"2.47032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210310000000e-324"));
// Rounding error
// Adapted from:
// https://www.exploringbinary.com/how-glibc-strtod-works/
assert_eq!(Ok((2.2250738585072011e-308, 1076)), parse(b"0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375"));
// Rounding error
// Adapted from test-parse-random failures.
assert_eq!(Ok((1.009e-28, 8)), parse(b"1009e-31"));
assert_eq!(Ok((f64::INFINITY, 9)), parse(b"18294e304"));
// Rounding error
// Adapted from a @dangrabcad's issue #20.
assert_eq!(Ok((7.689539722041643e164, 21)), parse(b"7.689539722041643e164"));
assert_eq!(Ok((7.689539722041643e164, 165)), parse(b"768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
assert_eq!(Ok((7.689539722041643e164, 167)), parse(b"768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0"));
// Check other cases similar to @dangrabcad's issue #20.
assert_eq!(Ok((9223372036854777856.0, 21)), parse(b"9223372036854776833.0"));
assert_eq!(
Ok((11417981541647681583767488212054764084468383744.0, 49)),
parse(b"11417981541647680316116887983825362587765178369.0")
);
assert_eq!(Ok((9007199254740996.0, 18)), parse(b"9007199254740995.0"));
assert_eq!(Ok((18014398509481992.0, 19)), parse(b"18014398509481990.0"));
assert_eq!(Ok((9223372036854779904.0, 21)), parse(b"9223372036854778880.0"));
assert_eq!(
Ok((11417981541647684119068688668513567077874794496.0, 49)),
parse(b"11417981541647682851418088440284165581171589120.0")
);
// Check other cases ostensibly identified via proptest.
assert_eq!(Ok((71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 310)), parse(b"71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0"));
assert_eq!(Ok((126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 311)), parse(b"126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0"));
assert_eq!(Ok((38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 310)), parse(b"38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0"));
// Round-trip for base2.
#[cfg(feature = "power-of-two")]
{
assert_eq!(
Ok((f64::from_bits(0x3bcd261840000000), 33)),
parse_binary(b"1.1101001001100001100001^-1000011")
);
}
// Check other bugs in Golang.
assert_eq!(Ok((1.0905441441816094e+30, 31)), parse(b"1090544144181609348835077142190"));
// Errors identified via test-parse-random.
assert_eq!(Ok((-7.014172639932773e-283, 23)), parse(b"-7.014172639932773e-283"));
assert_eq!(Ok((1.565385248817619e-82, 21)), parse(b"1.565385248817619e-82"));
// Errors identified in fast_float
assert_eq!(Ok((1.0905441441816094e+30, 31)), parse(b"1090544144181609348835077142190"));
assert_eq!(Ok((f64::INFINITY, 6)), parse(b"1e1000"));
assert_eq!(
Ok((-2.2400841322710136e+18, 57)),
parse(b"-2240084132271013504.131248280843119943687942846658579428")
);
// Errors identified via test-parse-golang.
assert_eq!(Ok((0.0, 25)), parse(b"1.00000000001e-2147483638"));
assert_eq!(Ok((0, 25)), parse(b"1.00000000001e-2147483638").map(|(x, y)| (x.to_bits(), y)));
}
#[test]
fn f64_decimal_test() {
// integer test
assert_eq!(0.0, f64::from_lexical(b"0").unwrap());
assert_eq!(1.0, f64::from_lexical(b"1").unwrap());
assert_eq!(12.0, f64::from_lexical(b"12").unwrap());
assert_eq!(123.0, f64::from_lexical(b"123").unwrap());
assert_eq!(1234.0, f64::from_lexical(b"1234").unwrap());
assert_eq!(12345.0, f64::from_lexical(b"12345").unwrap());
assert_eq!(123456.0, f64::from_lexical(b"123456").unwrap());
assert_eq!(1234567.0, f64::from_lexical(b"1234567").unwrap());
assert_eq!(12345678.0, f64::from_lexical(b"12345678").unwrap());
// No fraction after decimal point test
assert_eq!(1.0, f64::from_lexical(b"1.").unwrap());
assert_eq!(12.0, f64::from_lexical(b"12.").unwrap());
assert_eq!(1234567.0, f64::from_lexical(b"1234567.").unwrap());
// No integer before decimal point test
assert_eq!(0.1, f64::from_lexical(b".1").unwrap());
assert_eq!(0.12, f64::from_lexical(b".12").unwrap());
assert_eq!(0.1234567, f64::from_lexical(b".1234567").unwrap());
// decimal test
assert_eq!(123456789.0, f64::from_lexical(b"123456789").unwrap());
assert_eq!(123456789.1, f64::from_lexical(b"123456789.1").unwrap());
assert_eq!(123456789.12, f64::from_lexical(b"123456789.12").unwrap());
assert_eq!(123456789.123, f64::from_lexical(b"123456789.123").unwrap());
assert_eq!(123456789.1234, f64::from_lexical(b"123456789.1234").unwrap());
assert_eq!(123456789.12345, f64::from_lexical(b"123456789.12345").unwrap());
assert_eq!(123456789.123456, f64::from_lexical(b"123456789.123456").unwrap());
assert_eq!(123456789.1234567, f64::from_lexical(b"123456789.1234567").unwrap());
assert_eq!(123456789.12345678, f64::from_lexical(b"123456789.12345678").unwrap());
// rounding test
assert_eq!(123456789.12345679, f64::from_lexical(b"123456789.123456789").unwrap());
assert_eq!(123456789.12345679, f64::from_lexical(b"123456789.1234567890").unwrap());
assert_eq!(123456789.12345679, f64::from_lexical(b"123456789.123456789012").unwrap());
assert_eq!(123456789.12345679, f64::from_lexical(b"123456789.1234567890123").unwrap());
assert_eq!(123456789.12345679, f64::from_lexical(b"123456789.12345678901234").unwrap());
// exponent test
assert_eq!(123456789.12345, f64::from_lexical(b"1.2345678912345e8").unwrap());
assert_eq!(123450000.0, f64::from_lexical(b"1.2345e+8").unwrap());
assert_eq!(1.2345e+11, f64::from_lexical(b"123450000000").unwrap());
assert_eq!(1.2345e+11, f64::from_lexical(b"1.2345e+11").unwrap());
assert_eq!(1.2345e+38, f64::from_lexical(b"1.2345e+38").unwrap());
assert_eq!(1.2345e+38, f64::from_lexical(b"123450000000000000000000000000000000000").unwrap());
assert_eq!(1.2345e+308, f64::from_lexical(b"1.2345e+308").unwrap());
assert_eq!(1.2345e+308, f64::from_lexical(b"123450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(0.000000012345, f64::from_lexical(b"1.2345e-8").unwrap());
assert_eq!(1.2345e-8, f64::from_lexical(b"0.000000012345").unwrap());
assert_eq!(1.2345e-38, f64::from_lexical(b"1.2345e-38").unwrap());
assert_eq!(
1.2345e-38,
f64::from_lexical(b"0.000000000000000000000000000000000000012345").unwrap()
);
// denormalized (try extremely low values)
assert_eq!(1.2345e-308, f64::from_lexical(b"1.2345e-308").unwrap());
// due to issues in how the data is parsed, manually extracting
// non-exponents of 1.<e-299 is prone to error
// test the limit of our ability
// We tend to get relative errors of 1e-16, even at super low values.
assert_eq!(1.2345e-299, f64::from_lexical(b"0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012345").unwrap());
// Keep pushing from -300 to -324
assert_eq!(1.2345e-300, f64::from_lexical(b"0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012345").unwrap());
assert_eq!(1.2345e-310, f64::from_lexical(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012345").unwrap());
assert_eq!(1.2345e-320, f64::from_lexical(b"0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012345").unwrap());
assert_eq!(1.2345e-321, f64::from_lexical(b"0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012345").unwrap());
assert_eq!(1.24e-322, f64::from_lexical(b"0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124").unwrap());
assert_eq!(Ok(1e-323), f64::from_lexical(b"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"));
assert_eq!(Ok(5e-324), f64::from_lexical(b"0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005"));
assert!(f64::from_lexical(b"NaN").unwrap().is_nan());
assert!(f64::from_lexical(b"nan").unwrap().is_nan());
assert!(f64::from_lexical(b"NAN").unwrap().is_nan());
assert!(f64::from_lexical(b"inf").unwrap().is_infinite());
assert!(f64::from_lexical(b"INF").unwrap().is_infinite());
assert!(f64::from_lexical(b"+inf").unwrap().is_infinite());
assert!(f64::from_lexical(b"-inf").unwrap().is_infinite());
// Check various expected failures.
assert_eq!(Err(Error::Empty(0)), f64::from_lexical(b""));
assert_eq!(Err(Error::EmptyMantissa(0)), f64::from_lexical(b"e"));
assert_eq!(Err(Error::EmptyMantissa(0)), f64::from_lexical(b"E"));
assert_eq!(Err(Error::EmptyMantissa(1)), f64::from_lexical(b".e1"));
assert_eq!(Err(Error::EmptyMantissa(1)), f64::from_lexical(b".e-1"));
assert_eq!(Err(Error::EmptyMantissa(0)), f64::from_lexical(b"e1"));
assert_eq!(Err(Error::EmptyMantissa(0)), f64::from_lexical(b"e-1"));
// Check various reports from a fuzzer.
assert_eq!(Err(Error::EmptyExponent(2)), f64::from_lexical(b"0e"));
assert_eq!(Err(Error::EmptyExponent(4)), f64::from_lexical(b"0.0e"));
assert_eq!(Err(Error::EmptyMantissa(1)), f64::from_lexical(b".E"));
assert_eq!(Err(Error::EmptyMantissa(1)), f64::from_lexical(b".e"));
assert_eq!(Err(Error::EmptyMantissa(0)), f64::from_lexical(b"E2252525225"));
assert_eq!(Err(Error::EmptyMantissa(0)), f64::from_lexical(b"e2252525225"));
assert_eq!(Ok(f64::INFINITY), f64::from_lexical(b"2E200000000000"));
// Add various unittests from proptests.
assert_eq!(Err(Error::EmptyExponent(2)), f64::from_lexical(b"0e"));
assert_eq!(Err(Error::EmptyMantissa(1)), f64::from_lexical(b"."));
assert_eq!(Err(Error::EmptyMantissa(2)), f64::from_lexical(b"+."));
assert_eq!(Err(Error::EmptyMantissa(2)), f64::from_lexical(b"-."));
assert_eq!(Err(Error::Empty(1)), f64::from_lexical(b"+"));
assert_eq!(Err(Error::Empty(1)), f64::from_lexical(b"-"));
// Bug fix for Issue #8
assert_eq!(Ok(5.002868148396374), f64::from_lexical(b"5.002868148396374"));
// Other bug fixes
assert_eq!(Ok(1.620515050981309e+308), f64::from_lexical(b"162051505098130900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
assert_eq!(Ok(1.620515050981309e+308), f64::from_lexical(b"162051505098130900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0"));
assert_eq!(Ok(-1.620515050981309e+308), f64::from_lexical(b"-162051505098130900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
assert_eq!(Ok(-1.620515050981309e+308), f64::from_lexical(b"-162051505098130900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0"));
}
#[test]
#[cfg(feature = "radix")]
fn f64_radix_test() {
const FORMAT: u128 = NumberFormatBuilder::from_radix(36);
const CUSTOM: Options = Options::builder().exponent(b'^').build_strict();
assert_eq!(1234.0, f64::from_lexical_with_options::<FORMAT>(b"YA", &CUSTOM).unwrap());
const OPTIONS: Options = CUSTOM.rebuild().lossy(true).build_strict();
assert_eq!(1234.0, f64::from_lexical_with_options::<FORMAT>(b"YA", &OPTIONS).unwrap());
}
#[test]
fn parse_f64_large_zeros_test() {
// Test numbers with a massive number of 0s in the integer component.
let parse = move |x| f64::from_lexical_partial(x);
assert_eq!(Ok((71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 308)), parse(b"71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
assert_eq!(Ok((126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 309)), parse(b"126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
assert_eq!(Ok((38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 308)), parse(b"38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
}
#[test]
#[cfg(feature = "power-of-two")]
fn parse_binary_f64_test() {
#[cfg(feature = "power-of-two")]
let parse_binary = move |x| {
const BINARY: u128 = NumberFormatBuilder::from_radix(2);
const OPTIONS: Options = Options::builder().exponent(b'^').build_strict();
f64::from_lexical_partial_with_options::<BINARY>(x, &OPTIONS)
};
// Test a wide variety of denormal floats here.
// Halfway, round-up.
assert_eq!(
Ok((2.2250738585072009e-308, 65)),
parse_binary(b"1111111111111111111111111111111111111111111111111111^-10000110010")
);
assert_eq!(
Ok((2.2250738585072014e-308, 66)),
parse_binary(b"10000000000000000000000000000000000000000000000000000^-10000110010")
);
assert_eq!(
Ok((2.2250738585072009e-308, 66)),
parse_binary(b"11111111111111111111111111111111111111111111111111110^-10000110011")
);
assert_eq!(
Ok((2.2250738585072014e-308, 66)),
parse_binary(b"11111111111111111111111111111111111111111111111111111^-10000110011")
);
// Halfway, round-down.
assert_eq!(
Ok((2.2250738585072004e-308, 65)),
parse_binary(b"1111111111111111111111111111111111111111111111111110^-10000110010")
);
assert_eq!(
Ok((2.2250738585072004e-308, 66)),
parse_binary(b"11111111111111111111111111111111111111111111111111101^-10000110011")
);
// Force the moderate path (round-up).
assert_eq!(
Ok((2.2250738585072009e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111100000^-10000110111")
);
assert_eq!(
Ok((2.2250738585072009e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111101000^-10000110111")
);
assert_eq!(
Ok((2.2250738585072009e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111101111^-10000110111")
);
assert_eq!(
Ok((2.2250738585072014e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111110000^-10000110111")
);
assert_eq!(
Ok((2.2250738585072014e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111111111^-10000110111")
);
assert_eq!(
Ok((2.2250738585072014e-308, 70)),
parse_binary(b"100000000000000000000000000000000000000000000000000000000^-10000110110")
);
// Force the moderate path (round-down).
assert_eq!(
Ok((2.2250738585072004e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111000000^-10000110111")
);
assert_eq!(
Ok((2.2250738585072004e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111001000^-10000110111")
);
assert_eq!(
Ok((2.2250738585072004e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111001111^-10000110111")
);
assert_eq!(
Ok((2.2250738585072004e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111010000^-10000110111")
);
assert_eq!(
Ok((2.2250738585072009e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111010001^-10000110111")
);
assert_eq!(
Ok((2.2250738585072009e-308, 70)),
parse_binary(b"111111111111111111111111111111111111111111111111111011111^-10000110111")
);
// Let's test comically long digits (round-up).
assert_eq!(Ok((2.225073858507201e-308, 170)), parse_binary(b"1111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000^-10010011011"));
assert_eq!(Ok((2.225073858507201e-308, 170)), parse_binary(b"1111111111111111111111111111111111111111111111111111011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111^-10010011011"));
assert_eq!(Ok((2.2250738585072014e-308, 170)), parse_binary(b"1111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000^-10010011011"));
assert_eq!(Ok((2.2250738585072014e-308, 170)), parse_binary(b"1111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000^-10010011011"));
}
#[test]
fn parse_f32_lossy_test() {
const FORMAT: u128 = STANDARD;
const OPTIONS: Options = Options::builder().lossy(true).build_strict();
let parse = move |x| f32::from_lexical_partial_with_options::<FORMAT>(x, &OPTIONS);
assert_eq!(Ok((1.2345, 6)), parse(b"1.2345"));
assert_eq!(Ok((12.345, 6)), parse(b"12.345"));
assert_eq!(Ok((12345.6789, 10)), parse(b"12345.6789"));
assert_eq!(Ok((1.2345e10, 9)), parse(b"1.2345e10"));
}
#[test]
fn parse_f64_lossy_test() {
const FORMAT: u128 = STANDARD;
const OPTIONS: Options = Options::builder().lossy(true).build_strict();
let parse = move |x| f64::from_lexical_partial_with_options::<FORMAT>(x, &OPTIONS);
assert_eq!(Ok((1.2345, 6)), parse(b"1.2345"));
assert_eq!(Ok((12.345, 6)), parse(b"12.345"));
assert_eq!(Ok((12345.6789, 10)), parse(b"12345.6789"));
assert_eq!(Ok((1.2345e10, 9)), parse(b"1.2345e10"));
}
#[test]
fn f32_lossy_decimal_test() {
const FORMAT: u128 = STANDARD;
const OPTIONS: Options = Options::builder().lossy(true).build_strict();
assert_eq!(
Err(Error::EmptyMantissa(1)),
f32::from_lexical_with_options::<FORMAT>(b".", &OPTIONS)
);
assert_eq!(Err(Error::Empty(0)), f32::from_lexical_with_options::<FORMAT>(b"", &OPTIONS));
assert_eq!(Ok(0.0), f32::from_lexical_with_options::<FORMAT>(b"0.0", &OPTIONS));
assert_eq!(
Err((Error::InvalidDigit(1)).into()),
f32::from_lexical_with_options::<FORMAT>(b"1a", &OPTIONS)
);
// Bug fix for Issue #8
assert_eq!(
Ok(5.002868148396374),
f32::from_lexical_with_options::<FORMAT>(b"5.002868148396374", &OPTIONS)
);
}
#[test]
fn f64_lossy_decimal_test() {
const FORMAT: u128 = STANDARD;
const OPTIONS: Options = Options::builder().lossy(true).build_strict();
assert_eq!(
Err(Error::EmptyMantissa(1)),
f64::from_lexical_with_options::<FORMAT>(b".", &OPTIONS)
);
assert_eq!(Err(Error::Empty(0)), f64::from_lexical_with_options::<FORMAT>(b"", &OPTIONS));
assert_eq!(Ok(0.0), f64::from_lexical_with_options::<FORMAT>(b"0.0", &OPTIONS));
assert_eq!(
Err((Error::InvalidDigit(1)).into()),
f64::from_lexical_with_options::<FORMAT>(b"1a", &OPTIONS)
);
// Bug fix for Issue #8
assert_eq!(
Ok(5.002868148396374),
f64::from_lexical_with_options::<FORMAT>(b"5.002868148396374", &OPTIONS)
);
}
#[cfg(feature = "format")]
const fn rebuild(format: u128) -> NumberFormatBuilder {
NumberFormatBuilder::rebuild(format)
}
#[test]
#[cfg(feature = "format")]
fn f64_special_test() {
// Comments match (no_special, case_sensitive, has_sep)
const F1: u128 = STANDARD;
const F2: u128 = format::IGNORE;
const F3: u128 = rebuild(F1).no_special(true).build_strict();
const F4: u128 = rebuild(F1).case_sensitive_special(true).build_strict();
const F5: u128 = rebuild(F2).case_sensitive_special(true).build_strict();
const OPTIONS: Options = Options::new();
// Easy NaN
assert!(f64::from_lexical_with_options::<F1>(b"NaN", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F2>(b"NaN", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F3>(b"NaN", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F4>(b"NaN", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F5>(b"NaN", &OPTIONS).unwrap().is_nan());
// Case-sensitive NaN.
assert!(f64::from_lexical_with_options::<F1>(b"nan", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F2>(b"nan", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F3>(b"nan", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F4>(b"nan", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F5>(b"nan", &OPTIONS).is_err());
// Digit-separator NaN.
assert!(f64::from_lexical_with_options::<F1>(b"N_aN", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F2>(b"N_aN", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F3>(b"N_aN", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F4>(b"N_aN", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F5>(b"N_aN", &OPTIONS).unwrap().is_nan());
// Digit-separator + case-sensitive NaN.
assert!(f64::from_lexical_with_options::<F1>(b"n_an", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F2>(b"n_an", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F3>(b"n_an", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F4>(b"n_an", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F5>(b"n_an", &OPTIONS).is_err());
// Leading digit separator + case-sensitive NaN.
assert!(f64::from_lexical_with_options::<F1>(b"_n_a_n", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F2>(b"_n_a_n", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F3>(b"_n_a_n", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F4>(b"_n_a_n", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F5>(b"_n_a_n", &OPTIONS).is_err());
// Trailing digit separator + case-sensitive NaN.
assert!(f64::from_lexical_with_options::<F1>(b"n_a_n_", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F2>(b"n_a_n_", &OPTIONS).unwrap().is_nan());
assert!(f64::from_lexical_with_options::<F3>(b"n_a_n_", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F4>(b"n_a_n_", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F5>(b"n_a_n_", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn case_sensitive_exponent_test() {
const FORMAT: u128 = NumberFormatBuilder::new().case_sensitive_exponent(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e+300", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0E+300", &OPTIONS).is_err());
assert!(f64::from_lexical(b"+3.0e+300").is_ok());
assert!(f64::from_lexical(b"+3.0E+300").is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_integer_digits_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).required_integer_digits(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b".0", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_fraction_digits_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).required_fraction_digits(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_digits_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).required_digits(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b".0", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_no_positive_mantissa_sign_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).no_positive_mantissa_sign(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"-3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_mantissa_sign_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).required_mantissa_sign(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"-3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_no_exponent_notation_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).no_exponent_notation(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e-7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3e", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3e-", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_optional_exponent_test() {
const FORMAT: u128 = format::PERMISSIVE;
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e-7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e-", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_exponent_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).required_exponent_digits(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e-7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e-", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_no_positive_exponent_sign_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).no_positive_exponent_sign(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e+7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e-7", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_exponent_sign_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).required_exponent_sign(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e+7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e-7", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_no_exponent_without_fraction_test() {
const F1: u128 = rebuild(format::PERMISSIVE).no_exponent_without_fraction(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<F1>(b"3.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<F1>(b"3.e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<F1>(b"3e7", &OPTIONS).is_err());
const F2: u128 = rebuild(F1).required_fraction_digits(true).build_strict();
assert!(f64::from_lexical_with_options::<F2>(b"3.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<F2>(b"3.e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<F2>(b"3e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_no_leading_zeros_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE).no_float_leading_zeros(true).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"1.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"0.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"01.0", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"10.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"010.0", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_required_exponent_notation_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.required_exponent_digits(false)
.required_exponent_notation(true)
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"3.0e", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"0.e", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_integer_internal_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.integer_internal_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"3_1.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"_31.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31_.0e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_fraction_internal_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.fraction_internal_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.0_1e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31._01e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01_e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_exponent_internal_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.exponent_internal_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e7_1", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e_71", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e71_", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_integer_leading_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.integer_leading_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"3_1.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"_31.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31_.0e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_fraction_leading_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.fraction_leading_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.0_1e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31._01e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01_e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_exponent_leading_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.exponent_leading_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e7_1", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e_71", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e71_", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_integer_trailing_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.integer_trailing_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"3_1.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"_31.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31_.0e7", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_fraction_trailing_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.fraction_trailing_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.0_1e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31._01e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01_e7", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_exponent_trailing_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.exponent_trailing_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e7_1", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e_71", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e71_", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_integer_consecutive_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.integer_internal_digit_separator(true)
.integer_consecutive_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"3__1.0e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"_31.0e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31_.0e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_fraction_consecutive_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.fraction_internal_digit_separator(true)
.fraction_consecutive_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.0__1e7", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31._01e7", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01_e7", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_exponent_consecutive_digit_separator_test() {
const FORMAT: u128 = rebuild(format::PERMISSIVE)
.exponent_internal_digit_separator(true)
.exponent_consecutive_digit_separator(true)
.digit_separator(num::NonZeroU8::new(b'_'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e7__1", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e_71", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"31.01e71_", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_json_exponent_without_dot() {
// Tests courtesy of @ijl:
// https://github.com/Alexhuszagh/rust-lexical/issues/24#issuecomment-578153783
const FORMAT: u128 = format::JSON;
const OPTIONS: Options = Options::new();
// JSONTestSuite/test_parsing/y_number_0e1.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"0e1", &OPTIONS).is_ok());
// JSONTestSuite/test_parsing/y_number_int_with_exp.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"20e1", &OPTIONS).is_ok());
// JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"1E+2", &OPTIONS).is_ok());
// JSONTestSuite/test_transform/number_1e-999.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"1E-999", &OPTIONS).is_ok());
// nativejson-benchmark/data/jsonchecker/pass01.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"23456789012E66", &OPTIONS).is_ok());
}
#[test]
#[cfg(feature = "format")]
fn f64_json_exponent_requires_digit() {
// Tests courtesy of @ijl:
// https://github.com/Alexhuszagh/rust-lexical/issues/24#issuecomment-578153783
const FORMAT: u128 = format::JSON;
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"1e", &OPTIONS).is_err());
// JSONTestSuite/test_parsing/n_number_9.e+.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"9.e+", &OPTIONS).is_err());
// JSONTestSuite/test_parsing/n_number_2.e-3.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"2.e-3", &OPTIONS).is_err());
// JSONTestSuite/test_parsing/n_number_real_without_fractional_part.json
assert!(f64::from_lexical_with_options::<FORMAT>(b"1.", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn f64_json_no_leading_zero() {
const FORMAT: u128 = format::JSON;
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"12.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"-12.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"012.0", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"-012.0", &OPTIONS).is_err());
}
#[test]
#[cfg(all(feature = "power-of-two", feature = "format"))]
fn base_prefix_test() {
const FORMAT: u128 =
NumberFormatBuilder::new().base_prefix(num::NonZeroU8::new(b'x')).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x ", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3.0e+300", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3.0e+300", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3.0e+300 ", &OPTIONS).is_err());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+0x", &OPTIONS).is_err());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+0x ", &OPTIONS).is_err());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+0x3", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+0x3.0e+300", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+0x3.0e+300", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+0x3.0e+300 ", &OPTIONS).is_ok());
}
#[test]
#[cfg(all(feature = "power-of-two", feature = "format"))]
fn base_suffix_test() {
const FORMAT: u128 =
NumberFormatBuilder::new().base_suffix(num::NonZeroU8::new(b'h')).build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"h", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"-h ", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+h ", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e+300h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e+300h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3.0e+300h ", &OPTIONS).is_err());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+h", &OPTIONS).is_err());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+h ", &OPTIONS).is_err());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3h", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3.0", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3.0h", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3.0e+300h", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3.0e+300h", &OPTIONS).is_ok());
assert!(f64::from_lexical_partial_with_options::<FORMAT>(b"+3.0e+300h ", &OPTIONS).is_ok());
}
#[test]
#[cfg(all(feature = "power-of-two", feature = "format"))]
fn base_prefix_and_suffix_test() {
const FORMAT: u128 = NumberFormatBuilder::new()
.base_prefix(num::NonZeroU8::new(b'x'))
.base_suffix(num::NonZeroU8::new(b'h'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(f64::from_lexical_with_options::<FORMAT>(b"+3h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0xh", &OPTIONS).is_err());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3.0e+300h", &OPTIONS).is_ok());
assert!(f64::from_lexical_with_options::<FORMAT>(b"+0x3.0e+300h ", &OPTIONS).is_err());
}
#[test]
#[cfg(feature = "format")]
fn issue66_test() {
const RUST: u128 = format::RUST_LITERAL;
const JSON: u128 = format::JSON;
const CXX: u128 = format::CXX17_LITERAL;
const OPTIONS: Options = Options::new();
assert_eq!(f64::from_lexical_with_options::<JSON>(b"42.0", &OPTIONS), Ok(42.0));
assert_eq!(f64::from_lexical_with_options::<RUST>(b"42.0", &OPTIONS), Ok(42.0));
assert_eq!(f64::from_lexical_with_options::<RUST>(b"4_2.0", &OPTIONS), Ok(42.0));
assert_eq!(f64::from_lexical_with_options::<CXX>(b"42.0", &OPTIONS), Ok(42.0));
assert_eq!(f64::from_lexical_with_options::<CXX>(b"4'2.0", &OPTIONS), Ok(42.0));
}
#[test]
#[cfg(feature = "power-of-two")]
fn issue68_test() {
const FORMAT: u128 = NumberFormatBuilder::from_radix(16);
const OPTIONS: Options = Options::builder().exponent(b'^').build_strict();
// Roughly 2^1375, 15 1s.
let hex = b"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
assert_eq!(f32::INFINITY, f32::from_lexical_with_options::<FORMAT>(hex, &OPTIONS).unwrap());
assert_eq!(f64::INFINITY, f64::from_lexical_with_options::<FORMAT>(hex, &OPTIONS).unwrap());
}