@@ -389,6 +389,183 @@ assert Number.isInfinite(1/2) == false
389389assert Number.isInfinite(-1/2) == false
390390assert Number.isInfinite(BI.toNumber(-1t)) == false
391391
392+ // parseFloat
393+ // tests taken from Go's /src/strconv/atof_test.go
394+ assert Number.parseFloat("") == Err("Invalid string")
395+ assert Number.parseFloat("1") == Ok(1.)
396+ assert Number.parseFloat("+1") == Ok(1.)
397+ assert Number.parseFloat("1x") == Err("Invalid float")
398+ assert Number.parseFloat("1.1.") == Err("Invalid float")
399+ assert Number.parseFloat("1e23") == Ok(1e+23)
400+ assert Number.parseFloat("1E23") == Ok(1e+23)
401+ assert Number.parseFloat("100000000000000000000000") == Ok(1e+23)
402+ assert Number.parseFloat("1e-100") == Ok(1e-100)
403+ assert Number.parseFloat("123456700") == Ok(1.234567e+08)
404+ assert Number.parseFloat("99999999999999974834176") == Ok(9.999999999999997e+22)
405+ assert Number.parseFloat("100000000000000000000001") ==
406+ Ok(1.0000000000000001e+23)
407+ assert Number.parseFloat("100000000000000008388608") ==
408+ Ok(1.0000000000000001e+23)
409+ assert Number.parseFloat("100000000000000016777215") ==
410+ Ok(1.0000000000000001e+23)
411+ assert Number.parseFloat("100000000000000016777216") ==
412+ Ok(1.0000000000000003e+23)
413+ assert Number.parseFloat("-1") == Ok(-1.)
414+ assert Number.parseFloat("-0.1") == Ok(-0.1)
415+ assert Number.parseFloat("-0") == Ok(-0.0)
416+ assert Number.parseFloat("1e-20") == Ok(1e-20)
417+ assert Number.parseFloat("625e-3") == Ok(0.625)
418+ // zeros
419+ assert Number.parseFloat("0") == Ok(0.)
420+ assert Number.parseFloat("0e0") == Ok(0.)
421+ assert Number.parseFloat("-0e0") == Ok(-0.)
422+ assert Number.parseFloat("+0e0") == Ok(0.)
423+ assert Number.parseFloat("0e-0") == Ok(0.)
424+ assert Number.parseFloat("-0e-0") == Ok(-0.)
425+ assert Number.parseFloat("+0e-0") == Ok(0.)
426+ assert Number.parseFloat("0e+0") == Ok(0.)
427+ assert Number.parseFloat("-0e+0") == Ok(-0.)
428+ assert Number.parseFloat("+0e+0") == Ok(0.)
429+ assert Number.parseFloat("0e+01234567890123456789") == Ok(0.)
430+ assert Number.parseFloat("0.00e-01234567890123456789") == Ok(0.)
431+ assert Number.parseFloat("-0e+01234567890123456789") == Ok(-0.)
432+ assert Number.parseFloat("-0.00e-01234567890123456789") == Ok(-0.)
433+ assert Number.parseFloat("0e291") == Ok(0.)
434+ assert Number.parseFloat("0e292") == Ok(0.)
435+ assert Number.parseFloat("0e347") == Ok(0.)
436+ assert Number.parseFloat("0e348") == Ok(0.)
437+ // NaNs
438+ assert Number.isNaN(
439+ Result.expect("float should parse", Number.parseFloat("nan"))
440+ )
441+ assert Number.isNaN(
442+ Result.expect("float should parse", Number.parseFloat("NaN"))
443+ )
444+ assert Number.isNaN(
445+ Result.expect("float should parse", Number.parseFloat("NAN"))
446+ )
447+ // Infs
448+ assert Number.parseFloat("inf") == Ok(Number.infinity)
449+ assert Number.parseFloat("-Inf") == Ok(Number.neg(Number.infinity))
450+ assert Number.parseFloat("+INF") == Ok(Number.infinity)
451+ assert Number.parseFloat("-Infinity") == Ok(Number.neg(Number.infinity))
452+ assert Number.parseFloat("+INFINITY") == Ok(Number.infinity)
453+ assert Number.parseFloat("Infinity") == Ok(Number.infinity)
454+ // largest float64
455+ assert Number.parseFloat("1.7976931348623157e308") ==
456+ Ok(1.7976931348623157e+308)
457+ assert Number.parseFloat("-1.7976931348623157e308") ==
458+ Ok(-1.7976931348623157e+308)
459+ // next float64 - too large
460+ assert Number.parseFloat("1.7976931348623159e308") == Ok(Number.infinity)
461+ assert Number.parseFloat("-1.7976931348623159e308") ==
462+ Ok(Number.neg(Number.infinity))
463+ // the border is ...158079
464+ // borderline - okay
465+ assert Number.parseFloat("1.7976931348623158079e308") ==
466+ Ok(1.7976931348623157e+308)
467+ assert Number.parseFloat("-1.7976931348623158079e308") ==
468+ Ok(-1.7976931348623157e+308)
469+ // borderline - too large
470+ assert Number.parseFloat("1.797693134862315808e308") == Ok(Number.infinity)
471+ assert Number.parseFloat("-1.797693134862315808e308") ==
472+ Ok(Number.neg(Number.infinity))
473+ // a little too large
474+ assert Number.parseFloat("1e308") == Ok(1e+308)
475+ assert Number.parseFloat("2e308") == Ok(Number.infinity)
476+ assert Number.parseFloat("1e309") == Ok(Number.infinity)
477+ // way too large
478+ assert Number.parseFloat("1e310") == Ok(Number.infinity)
479+ assert Number.parseFloat("-1e310") == Ok(Number.neg(Number.infinity))
480+ assert Number.parseFloat("1e400") == Ok(Number.infinity)
481+ assert Number.parseFloat("-1e400") == Ok(Number.neg(Number.infinity))
482+ assert Number.parseFloat("1e400000") == Ok(Number.infinity)
483+ assert Number.parseFloat("-1e400000") == Ok(Number.neg(Number.infinity))
484+ // denormalized
485+ assert Number.parseFloat("1e-305") == Ok(1e-305)
486+ assert Number.parseFloat("1e-306") == Ok(1e-306)
487+ assert Number.parseFloat("1e-307") == Ok(1e-307)
488+ assert Number.parseFloat("1e-308") == Ok(1e-308)
489+ assert Number.parseFloat("1e-309") == Ok(1e-309)
490+ assert Number.parseFloat("1e-310") == Ok(1e-310)
491+ assert Number.parseFloat("1e-322") == Ok(1e-322)
492+ // smallest denormal
493+ assert Number.parseFloat("5e-324") == Ok(5e-324)
494+ assert Number.parseFloat("4e-324") == Ok(5e-324)
495+ assert Number.parseFloat("3e-324") == Ok(5e-324)
496+ // too small
497+ assert Number.parseFloat("2e-324") == Ok(0.)
498+ // way too small
499+ assert Number.parseFloat("1e-350") == Ok(0.)
500+ assert Number.parseFloat("1e-400000") == Ok(0.)
501+ // try to overflow exponent
502+ assert Number.parseFloat("1e-4294967296") == Ok(0.)
503+ assert Number.parseFloat("1e+4294967296") == Ok(Number.infinity)
504+ assert Number.parseFloat("1e-18446744073709551616") == Ok(0.)
505+ assert Number.parseFloat("1e+18446744073709551616") == Ok(Number.infinity)
506+ // Parse errors
507+ assert Number.parseFloat("1e") == Err("Invalid exponent")
508+ assert Number.parseFloat("1e-") == Err("Invalid exponent")
509+ assert Number.parseFloat(".e-1") == Err("Invalid float")
510+ // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
511+ assert Number.parseFloat("2.2250738585072012e-308") ==
512+ Ok(2.2250738585072014e-308)
513+ // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
514+ assert Number.parseFloat("2.2250738585072011e-308") ==
515+ Ok(2.225073858507201e-308)
516+ // A different kind of very large number.
517+ assert Number.parseFloat("22.222222222222222") == Ok(22.22222222222222)
518+ assert Number.parseFloat(
519+ "2.222222222222222222222222222222222222222222222222222222222222222222222222222e+1"
520+ ) ==
521+ Ok(22.22222222222222)
522+ // Exactly halfway between 1 and math.Nextafter(1, 2).
523+ // Round to even (down).
524+ assert Number.parseFloat(
525+ "1.00000000000000011102230246251565404236316680908203125"
526+ ) ==
527+ Ok(1.)
528+ // Slightly lower; still round down.
529+ assert Number.parseFloat(
530+ "1.00000000000000011102230246251565404236316680908203124"
531+ ) ==
532+ Ok(1.)
533+ // Slightly higher; round up.
534+ assert Number.parseFloat(
535+ "1.00000000000000011102230246251565404236316680908203126"
536+ ) ==
537+ Ok(1.0000000000000002)
538+ // Slightly higher, but you have to read all the way to the end.
539+ assert Number.parseFloat(
540+ "1.0000000000000001110223024625156540423631668090820312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
541+ ) ==
542+ Ok(1.0000000000000002)
543+ // Halfway between x := math.Nextafter(1, 2) and math.Nextafter(x, 2)
544+ // Round to even (up).
545+ assert Number.parseFloat(
546+ "1.00000000000000033306690738754696212708950042724609375"
547+ ) ==
548+ Ok(1.0000000000000004)
549+ // Halfway between 1090544144181609278303144771584 and 1090544144181609419040633126912
550+ assert Number.parseFloat("1090544144181609348671888949248") ==
551+ Ok(1.0905441441816093e+30)
552+ // slightly above, rounds up
553+ assert Number.parseFloat("1090544144181609348835077142190") ==
554+ Ok(1.0905441441816094e+30)
555+ // underscores
556+ assert Number.parseFloat("1__") == Ok(1.)
557+ assert Number.parseFloat("1_e2_3_") == Ok(1e+23)
558+ assert Number.parseFloat("100_000_000_000_000_000_000_000") == Ok(1e+23)
559+ assert Number.parseFloat("1_2345_6700") == Ok(1.234567e+08)
560+ assert Number.parseFloat("625e-3__") == Ok(0.625)
561+ assert Number.parseFloat("0_0e+0_12__3___4____567890123456789") == Ok(0.)
562+ assert Number.parseFloat("1_e400_000") == Ok(Number.infinity)
563+ assert Number.parseFloat("-1_e400_000") == Ok(Number.neg(Number.infinity))
564+ assert Number.parseFloat(
565+ "1.000_000_000_000_000_111_022_302_462_515_654_042_363_166_809_082_031_250_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_1"
566+ ) ==
567+ Ok(1.0000000000000002)
568+
392569// parseInt
393570assert Number.parseInt("42", 10) == Ok(42)
394571assert Number.parseInt("042", 10) == Ok(42)
0 commit comments