diff --git a/crates/typst/src/foundations/float.rs b/crates/typst/src/foundations/float.rs index 4b38bdf98..6bcebda88 100644 --- a/crates/typst/src/foundations/float.rs +++ b/crates/typst/src/foundations/float.rs @@ -47,6 +47,53 @@ impl f64 { ) -> f64 { value.0 } + + /// Checks if a float is not a number. + /// + /// In IEEE 754, more than one bit pattern represents a NaN. This function + /// returns `true` if the float is any of those bit patterns. + /// + /// ```example + /// #float.is-nan(0) \ + /// #float.is-nan(1) \ + /// #float.is-nan(calc.nan) + /// ``` + #[func] + pub fn is_nan(self) -> bool { + f64::is_nan(self) + } + + /// Checks if a float is infinite. + /// + /// For floats, there is positive and negative infinity. This function + /// returns `true` if the float is either positive or negative infinity. + /// + /// ```example + /// #float.is-infinite(0) \ + /// #float.is-infinite(1) \ + /// #float.is-infinite(calc.inf) + /// ``` + #[func] + pub fn is_infinite(self) -> bool { + f64::is_infinite(self) + } + + /// Calculates the sign of a floating point number. + /// + /// - If the number is positive (including `{+0.0}`), returns `{1.0}`. + /// - If the number is negative (including `{-0.0}`), returns `{-1.0}`. + /// - If the number is [`{calc.nan}`]($calc.nan), returns + /// [`{calc.nan}`]($calc.nan). + /// + /// ```example + /// #(5.0).signum() \ + /// #(-5.0).signum() \ + /// #(0.0).signum() \ + /// ``` + #[func] + pub fn signum(self) -> f64 { + f64::signum(self) + } } impl Repr for f64 { diff --git a/crates/typst/src/foundations/int.rs b/crates/typst/src/foundations/int.rs index 88b0413ab..602cdd5ae 100644 --- a/crates/typst/src/foundations/int.rs +++ b/crates/typst/src/foundations/int.rs @@ -49,6 +49,22 @@ impl i64 { ) -> i64 { value.0 } + + /// Calculates the sign of an integer. + /// + /// - If the number is positive, returns `{1}`. + /// - If the number is negative, returns `{-1}`. + /// - If the number is zero, returns `{0}`. + /// + /// ```example + /// #(5).signum() \ + /// #(-5).signum() \ + /// #(0).signum() \ + /// ``` + #[func] + pub fn signum(self) -> i64 { + i64::signum(self) + } } impl Repr for i64 { diff --git a/tests/typ/compute/calc.typ b/tests/typ/compute/calc.typ index e61e15d47..68f76b39c 100644 --- a/tests/typ/compute/calc.typ +++ b/tests/typ/compute/calc.typ @@ -19,6 +19,35 @@ #test(float("\u{2212}7654.321"), -7654.321) #test(type(float(10)), float) +--- +// Test float `is-nan()`. +#test(float(calc.nan).is-nan(), true) +#test(float(10).is-nan(), false) + +--- +// Test float `is-infinite()`. +#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 `signum()` +#test(float(0.0).signum(), 1.0) +#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(calc.nan).signum().is-nan(), true) + +--- +// Test int `signum()` +#test(int(0).signum(), 0) +#test(int(1.0).signum(), 1) +#test(int(-1.0).signum(), -1) +#test(int(10.0).signum(), 1) +#test(int(-10.0).signum(), -1) + --- #test(calc.round(calc.e, digits: 2), 2.72) #test(calc.round(calc.pi, digits: 2), 3.14)