From 6ce4756d55adb17ae9360785a88832156c400996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Hatcher=20Andr=C3=A9s?= Date: Thu, 30 Oct 2025 23:45:29 +0100 Subject: [PATCH] UPDATE: Adds DEGREES and RADIANS (#493) --- base/src/expressions/parser/static_analysis.rs | 4 ++++ base/src/functions/mathematical.rs | 2 ++ base/src/functions/mod.rs | 14 +++++++++++++- xlsx/tests/calc_tests/RADIANS_DEGREES.xlsx | Bin 0 -> 9316 bytes 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 xlsx/tests/calc_tests/RADIANS_DEGREES.xlsx diff --git a/base/src/expressions/parser/static_analysis.rs b/base/src/expressions/parser/static_analysis.rs index 50e9d82..c198a47 100644 --- a/base/src/expressions/parser/static_analysis.rs +++ b/base/src/expressions/parser/static_analysis.rs @@ -846,6 +846,8 @@ fn get_function_args_signature(kind: &Function, arg_count: usize) -> Vec args_signature_scalars(arg_count, 1, 0), Function::Factdouble => args_signature_scalars(arg_count, 1, 0), Function::Sign => args_signature_scalars(arg_count, 1, 0), + Function::Radians => args_signature_scalars(arg_count, 1, 0), + Function::Degrees => args_signature_scalars(arg_count, 1, 0), } } @@ -1080,5 +1082,7 @@ fn static_analysis_on_function(kind: &Function, args: &[Node]) -> StaticResult { Function::Fact => scalar_arguments(args), Function::Factdouble => scalar_arguments(args), Function::Sign => scalar_arguments(args), + Function::Radians => scalar_arguments(args), + Function::Degrees => scalar_arguments(args), } } diff --git a/base/src/functions/mathematical.rs b/base/src/functions/mathematical.rs index 549d9c6..6fee9c1 100644 --- a/base/src/functions/mathematical.rs +++ b/base/src/functions/mathematical.rs @@ -485,6 +485,8 @@ impl Model { Ok(acc) }); single_number_fn!(fn_sign, |f| Ok(f64::signum(f))); + single_number_fn!(fn_degrees, |f| Ok(f * (180.0 / PI))); + single_number_fn!(fn_radians, |f| Ok(f * (PI / 180.0))); pub(crate) fn fn_pi(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult { if !args.is_empty() { diff --git a/base/src/functions/mod.rs b/base/src/functions/mod.rs index fcc5f9f..79e3432 100644 --- a/base/src/functions/mod.rs +++ b/base/src/functions/mod.rs @@ -90,6 +90,9 @@ pub enum Function { Factdouble, Sign, + Radians, + Degrees, + // Information ErrorType, Formulatext, @@ -283,7 +286,7 @@ pub enum Function { } impl Function { - pub fn into_iter() -> IntoIter { + pub fn into_iter() -> IntoIter { [ Function::And, Function::False, @@ -334,6 +337,8 @@ impl Function { Function::Product, Function::Rand, Function::Randbetween, + Function::Radians, + Function::Degrees, Function::Round, Function::Rounddown, Function::Roundup, @@ -607,6 +612,9 @@ impl Function { "EXP" => Some(Function::Exp), "SIGN" => Some(Function::Sign), + "RADIANS" => Some(Function::Radians), + "DEGREES" => Some(Function::Degrees), + "PI" => Some(Function::Pi), "ABS" => Some(Function::Abs), "SQRT" => Some(Function::Sqrt), @@ -1051,6 +1059,8 @@ impl fmt::Display for Function { Function::Fact => write!(f, "FACT"), Function::Factdouble => write!(f, "FACTDOUBLE"), Function::Sign => write!(f, "SIGN"), + Function::Radians => write!(f, "RADIANS"), + Function::Degrees => write!(f, "DEGREES"), } } } @@ -1306,6 +1316,8 @@ impl Model { Function::Fact => self.fn_fact(args, cell), Function::Factdouble => self.fn_factdouble(args, cell), Function::Sign => self.fn_sign(args, cell), + Function::Radians => self.fn_radians(args, cell), + Function::Degrees => self.fn_degrees(args, cell), } } } diff --git a/xlsx/tests/calc_tests/RADIANS_DEGREES.xlsx b/xlsx/tests/calc_tests/RADIANS_DEGREES.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6c8ac842fc72094d423c0e10f01f120bf3d36057 GIT binary patch literal 9316 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