diff --git a/Cargo.lock b/Cargo.lock index e7335de7acb..855ac771267 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,7 @@ dependencies = [ "rand", "regex", "rustc-hash", + "ryu-js", "serde", "serde_json", ] @@ -693,6 +694,11 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "ryu-js" +version = "1.0.5" +source = "git+https://github.com/Tropid/ryu-js#fe366fa397d04324fa693b5d85134851b09719b3" + [[package]] name = "same-file" version = "1.0.6" diff --git a/boa/Cargo.toml b/boa/Cargo.toml index b8b28f45d35..e18f4409c79 100644 --- a/boa/Cargo.toml +++ b/boa/Cargo.toml @@ -23,6 +23,7 @@ rustc-hash = "1.1.0" num-bigint = { version = "0.3.0", features = ["serde"] } num-integer = "0.1.43" bitflags = "1.2.1" +ryu-js = { git = "https://github.com/Tropid/ryu-js" } # Optional Dependencies serde = { version = "1.0.111", features = ["derive"], optional = true } diff --git a/boa/src/builtins/value/display.rs b/boa/src/builtins/value/display.rs index fef09251920..5b8c5c596df 100644 --- a/boa/src/builtins/value/display.rs +++ b/boa/src/builtins/value/display.rs @@ -186,19 +186,15 @@ impl Display for ValueData { None => write!(f, "Symbol()"), }, Self::String(ref v) => write!(f, "{}", v), - Self::Rational(v) => write!( - f, - "{}", - match v { - _ if v.is_nan() => "NaN".to_string(), - _ if v.is_infinite() && v.is_sign_negative() => "-Infinity".to_string(), - _ if v.is_infinite() => "Infinity".to_string(), - _ => v.to_string(), - } - ), + Self::Rational(v) => format_rational(*v, f), Self::Object(_) => write!(f, "{}", log_string_from(self, true)), Self::Integer(v) => write!(f, "{}", v), Self::BigInt(ref num) => write!(f, "{}n", num), } } } + +fn format_rational(v: f64, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buffer = ryu_js::Buffer::new(); + write!(f, "{}", buffer.format(v)) +} diff --git a/boa/src/builtins/value/tests.rs b/boa/src/builtins/value/tests.rs index 008b04076ad..feb53e9dc3d 100644 --- a/boa/src/builtins/value/tests.rs +++ b/boa/src/builtins/value/tests.rs @@ -213,3 +213,28 @@ fn get_types() { Type::Symbol ); } + +#[test] +fn to_string() { + let f64_to_str = |f| { ValueData::Rational(f).to_string() }; + + assert_eq!(f64_to_str(f64::NAN), "NaN"); + assert_eq!(f64_to_str(0.0), "0"); + assert_eq!(f64_to_str(f64::INFINITY), "Infinity"); + assert_eq!(f64_to_str(f64::NEG_INFINITY), "-Infinity"); + assert_eq!(f64_to_str(90.12), "90.12"); + assert_eq!(f64_to_str(111111111111111111111.0), "111111111111111110000"); + assert_eq!(f64_to_str(1111111111111111111111.0), "1.1111111111111111e+21"); + + assert_eq!(f64_to_str(-90.12), "-90.12"); + + assert_eq!(f64_to_str(-111111111111111111111.0), "-111111111111111110000"); + assert_eq!(f64_to_str(-1111111111111111111111.0), "-1.1111111111111111e+21"); + + assert_eq!(f64_to_str(0.0000001), "1e-7"); + assert_eq!(f64_to_str(0.000001), "0.000001"); + assert_eq!(f64_to_str(0.0000002), "2e-7"); + assert_eq!(f64_to_str(-0.0000001), "-1e-7"); + + assert_eq!(f64_to_str(3e50), "3e+50"); +}