Fix calc.inf
, -calc.inf
, and calc.nan
reprs and displays (#4724)
@ -73,12 +73,15 @@ pub fn format_int_with_base(mut n: i64, base: i64) -> EcoString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a float to a string representation with a specific precision and a
|
/// Converts a float to a string representation with a specific precision and a
|
||||||
/// suffix, all with a single allocation.
|
/// unit, all with a single allocation.
|
||||||
|
///
|
||||||
|
/// The returned string is always valid Typst code. As such, it might not be a
|
||||||
|
/// float literal. For example, it may return `"calc.inf"`.
|
||||||
pub fn format_float(
|
pub fn format_float(
|
||||||
mut value: f64,
|
mut value: f64,
|
||||||
precision: Option<u8>,
|
precision: Option<u8>,
|
||||||
force_separator: bool,
|
force_separator: bool,
|
||||||
suffix: &str,
|
unit: &str,
|
||||||
) -> EcoString {
|
) -> EcoString {
|
||||||
if let Some(p) = precision {
|
if let Some(p) = precision {
|
||||||
let offset = 10_f64.powi(p as i32);
|
let offset = 10_f64.powi(p as i32);
|
||||||
@ -86,12 +89,16 @@ pub fn format_float(
|
|||||||
}
|
}
|
||||||
// Debug for f64 always prints a decimal separator, while Display only does
|
// Debug for f64 always prints a decimal separator, while Display only does
|
||||||
// when necessary.
|
// when necessary.
|
||||||
|
let unit_multiplication = if unit.is_empty() { "" } else { " * 1" };
|
||||||
if value.is_nan() {
|
if value.is_nan() {
|
||||||
"NaN".into()
|
eco_format!("calc.nan{unit_multiplication}{unit}")
|
||||||
|
} else if value.is_infinite() {
|
||||||
|
let sign = if value < 0.0 { "-" } else { "" };
|
||||||
|
eco_format!("{sign}calc.inf{unit_multiplication}{unit}")
|
||||||
} else if force_separator {
|
} else if force_separator {
|
||||||
eco_format!("{:?}{}", value, suffix)
|
eco_format!("{value:?}{unit}")
|
||||||
} else {
|
} else {
|
||||||
eco_format!("{}{}", value, suffix)
|
eco_format!("{value}{unit}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +119,9 @@ pub fn format_float_with_unit(value: f64, unit: &str) -> EcoString {
|
|||||||
pub fn display_float(value: f64) -> EcoString {
|
pub fn display_float(value: f64) -> EcoString {
|
||||||
if value.is_nan() {
|
if value.is_nan() {
|
||||||
"NaN".into()
|
"NaN".into()
|
||||||
|
} else if value.is_infinite() {
|
||||||
|
let sign = if value < 0.0 { MINUS_SIGN } else { "" };
|
||||||
|
eco_format!("{sign}∞")
|
||||||
} else if value < 0.0 {
|
} else if value < 0.0 {
|
||||||
eco_format!("{}{}", MINUS_SIGN, value.abs())
|
eco_format!("{}{}", MINUS_SIGN, value.abs())
|
||||||
} else {
|
} else {
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.4 KiB |
@ -20,6 +20,8 @@
|
|||||||
// Test float `is-nan()`.
|
// Test float `is-nan()`.
|
||||||
#test(float(calc.nan).is-nan(), true)
|
#test(float(calc.nan).is-nan(), true)
|
||||||
#test(float(10).is-nan(), false)
|
#test(float(10).is-nan(), false)
|
||||||
|
#test(float(calc.inf).is-nan(), false)
|
||||||
|
#test(float(-calc.inf).is-nan(), false)
|
||||||
|
|
||||||
--- float-is-infinite ---
|
--- float-is-infinite ---
|
||||||
// Test float `is-infinite()`.
|
// Test float `is-infinite()`.
|
||||||
@ -27,6 +29,7 @@
|
|||||||
#test(float(-calc.inf).is-infinite(), true)
|
#test(float(-calc.inf).is-infinite(), true)
|
||||||
#test(float(10).is-infinite(), false)
|
#test(float(10).is-infinite(), false)
|
||||||
#test(float(-10).is-infinite(), false)
|
#test(float(-10).is-infinite(), false)
|
||||||
|
#test(float(calc.nan).is-infinite(), false)
|
||||||
|
|
||||||
--- float-signum ---
|
--- float-signum ---
|
||||||
// Test float `signum()`
|
// Test float `signum()`
|
||||||
@ -35,6 +38,8 @@
|
|||||||
#test(float(-1.0).signum(), -1.0)
|
#test(float(-1.0).signum(), -1.0)
|
||||||
#test(float(10.0).signum(), 1.0)
|
#test(float(10.0).signum(), 1.0)
|
||||||
#test(float(-10.0).signum(), -1.0)
|
#test(float(-10.0).signum(), -1.0)
|
||||||
|
#test(float(calc.inf).signum(), 1.0)
|
||||||
|
#test(float(-calc.inf).signum(), -1.0)
|
||||||
#test(float(calc.nan).signum().is-nan(), true)
|
#test(float(calc.nan).signum().is-nan(), true)
|
||||||
|
|
||||||
--- float-repr ---
|
--- float-repr ---
|
||||||
@ -49,7 +54,10 @@
|
|||||||
#repr(-9876543210.0) \
|
#repr(-9876543210.0) \
|
||||||
#repr(-0987654321.0) \
|
#repr(-0987654321.0) \
|
||||||
#repr(-3.14) \
|
#repr(-3.14) \
|
||||||
#repr(4.0 - 8.0)
|
#repr(4.0 - 8.0) \
|
||||||
|
#repr(calc.inf) \
|
||||||
|
#repr(-calc.inf) \
|
||||||
|
#repr(calc.nan)
|
||||||
|
|
||||||
--- float-display ---
|
--- float-display ---
|
||||||
// Test floats.
|
// Test floats.
|
||||||
@ -63,4 +71,7 @@
|
|||||||
#(-9876543210.0) \
|
#(-9876543210.0) \
|
||||||
#(-0987654321.0) \
|
#(-0987654321.0) \
|
||||||
#(-3.14) \
|
#(-3.14) \
|
||||||
#(4.0 - 8.0)
|
#(4.0 - 8.0) \
|
||||||
|
#calc.inf \
|
||||||
|
#(-calc.inf) \
|
||||||
|
#calc.nan
|
||||||
|
@ -335,7 +335,7 @@
|
|||||||
#(1em <= 10pt)
|
#(1em <= 10pt)
|
||||||
|
|
||||||
--- ops-compare-normal-float-with-nan ---
|
--- ops-compare-normal-float-with-nan ---
|
||||||
// Error: 3-22 cannot compare 2.2 with NaN
|
// Error: 3-22 cannot compare 2.2 with calc.nan
|
||||||
#(2.2 <= float("nan"))
|
#(2.2 <= float("nan"))
|
||||||
|
|
||||||
--- ops-compare-int-and-str ---
|
--- ops-compare-int-and-str ---
|
||||||
@ -343,7 +343,7 @@
|
|||||||
#((0, 1, 3) > (0, 1, "a"))
|
#((0, 1, 3) > (0, 1, "a"))
|
||||||
|
|
||||||
--- ops-compare-array-nested-failure ---
|
--- ops-compare-array-nested-failure ---
|
||||||
// Error: 3-42 cannot compare 3.5 with NaN
|
// Error: 3-42 cannot compare 3.5 with calc.nan
|
||||||
#((0, "a", 3.5) <= (0, "a", float("nan")))
|
#((0, "a", 3.5) <= (0, "a", float("nan")))
|
||||||
|
|
||||||
--- ops-divide-by-zero-float ---
|
--- ops-divide-by-zero-float ---
|
||||||
|