Expressions: sign(0) is 0, not 1 (#10996)

This commit is contained in:
Steve Jason
2026-11-02 13:47:34 +00:00
committed by GitHub
parent 2339510e41
commit f484457c3b
+15 -1
View File
@@ -972,7 +972,11 @@ fn call(f: &str, args: &[Value], d: Defaults) -> Result<Value, DocError> {
let a = one()?;
unit_fn(a.v.abs(), a)
}
"sign" => Value::num(one()?.v.signum()),
"sign" => {
let x = one()?.v;
// `f64::signum` gives 1 for +0 and -1 for -0; the sign of zero is 0.
Value::num(if x == 0.0 { 0.0 } else { x.signum() })
}
"floor" | "ceil" | "round" | "trunc" => {
let a = one()?;
// Round in the value's own default unit (round(2.4 in) = 2 in for an inch parameter).
@@ -1430,6 +1434,16 @@ mod tests {
}
}
/// `sign(0)` is 0, not 1 (Rust's `signum` takes the sign bit, so it calls zero positive).
#[test]
fn sign_of_zero_is_zero() {
for (e, want) in
[("sign(0)", 0.0), ("sign(-0)", 0.0), ("sign(0 mm)", 0.0), ("sign(5)", 1.0), ("sign(-2 mm)", -1.0), ("sign(width - 40)", 0.0)]
{
assert_eq!(ev(e, Kind::Unitless).unwrap(), want, "{e}");
}
}
/// A count from a length (`(L - 20) / 210`, the 210 read as unit-less) names the fix (#5901).
#[test]
fn a_length_where_a_count_is_expected_says_to_divide_by_a_length() {