From a2d11a42cc3598decbc691de16c77e0f68707c91 Mon Sep 17 00:00:00 2001 From: Elsa Minsut Date: Fri, 7 Nov 2025 10:26:01 +0700 Subject: [PATCH] update: adds docs, unit tests and xlsx tests for EVEN and ODD functions (#517) * update: adds unit test for EVEN and ODD functions * update: adds xlsx test for EVEN and ODD functions * update: adds EVEN and ODD doc pages * update: Math and Trigonometry main page links to new functions * update: changes to functions badge type in main Math and Trigonometry page --- base/src/test/test_even_odd | 23 ++++++++++ docs/src/functions/math-and-trigonometry.md | 12 ++--- .../functions/math_and_trigonometry/even.md | 42 +++++++++++++++--- .../functions/math_and_trigonometry/odd.md | 42 +++++++++++++++--- xlsx/tests/calc_tests/EVEN_ODD.xlsx | Bin 0 -> 11185 bytes 5 files changed, 103 insertions(+), 16 deletions(-) create mode 100644 base/src/test/test_even_odd create mode 100644 xlsx/tests/calc_tests/EVEN_ODD.xlsx diff --git a/base/src/test/test_even_odd b/base/src/test/test_even_odd new file mode 100644 index 0000000..d406aeb --- /dev/null +++ b/base/src/test/test_even_odd @@ -0,0 +1,23 @@ +#![allow(clippy::unwrap_used)] + +use crate::test::util::new_empty_model; + +#[test] +fn arguments() { + let mut model = new_empty_model(); + model._set("A1", "=EVEN(2)"); + model._set("A2", "=ODD(2)"); + model._set("A3", "=EVEN()"); + model._set("A4", "=ODD()"); + model._set("A5", "=EVEN(1, 2)"); + model._set("A6", "=ODD(1, 2)"); + + model.evaluate(); + + assert_eq!(model._get_text("A1"), *"2"); + assert_eq!(model._get_text("A2"), *"3"); + assert_eq!(model._get_text("A3"), *"#ERROR!"); + assert_eq!(model._get_text("A4"), *"#ERROR!"); + assert_eq!(model._get_text("A5"), *"#ERROR!"); + assert_eq!(model._get_text("A6"), *"#ERROR!"); +} diff --git a/docs/src/functions/math-and-trigonometry.md b/docs/src/functions/math-and-trigonometry.md index f2d8f3b..7209afb 100644 --- a/docs/src/functions/math-and-trigonometry.md +++ b/docs/src/functions/math-and-trigonometry.md @@ -37,7 +37,7 @@ You can track the progress in this [GitHub issue](https://github.com/ironcalc/Ir | CSCH | | – | | DECIMAL | | – | | DEGREES | | [DEGREES](math_and_trigonometry/degrees) | -| EVEN | | – | +| EVEN | | [EVEN](math_and_trigonometry/even) | | EXP | | – | | FACT | | – | | FACTDOUBLE | | – | @@ -49,9 +49,9 @@ You can track the progress in this [GitHub issue](https://github.com/ironcalc/Ir | ISO.CEILING | | – | | LCM | | – | | LET | | – | -| LN | | – | -| LOG | | – | -| LOG10 | | – | +| LN | | – | +| LOG | | – | +| LOG10 | | – | | MDETERM | | – | | MINVERSE | | – | | MMULT | | – | @@ -59,7 +59,7 @@ You can track the progress in this [GitHub issue](https://github.com/ironcalc/Ir | MROUND | | – | | MULTINOMIAL | | – | | MUNIT | | – | -| ODD | | – | +| ODD | | [ODD](math_and_trigonometry/odd) | | PI | | – | | POWER | | – | | PRODUCT | | – | @@ -80,7 +80,7 @@ You can track the progress in this [GitHub issue](https://github.com/ironcalc/Ir | SIN | | [SIN](math_and_trigonometry/sin) | | SINH | | [SINH](math_and_trigonometry/sinh) | | SQRT | | – | -| SQRTPI | | – | +| SQRTPI | | – | | SUBTOTAL | | – | | SUM | | – | | SUMIF | | – | diff --git a/docs/src/functions/math_and_trigonometry/even.md b/docs/src/functions/math_and_trigonometry/even.md index 2998918..ea97082 100644 --- a/docs/src/functions/math_and_trigonometry/even.md +++ b/docs/src/functions/math_and_trigonometry/even.md @@ -4,9 +4,41 @@ outline: deep lang: en-US --- -# EVEN +# EVEN function -::: warning -🚧 This function is not yet available in IronCalc. -[Follow development here](https://github.com/ironcalc/IronCalc/labels/Functions) -::: \ No newline at end of file +## Overview +EVEN is a function of the Math and Trigonometry category that rounds a number up (away from zero) to the nearest even integer. + +## Usage +### Syntax +**EVEN(number) => even** + +### Argument descriptions +* *number* ([number](/features/value-types#numbers), required). The number that is to be rounded to the nearest even integer. + +### Additional guidance +* EVEN rounds away from zero, meaning: + * Positive numbers are rounded up to the next even integer. + * Negative numbers are rounded down (toward negative infinity) to the next even integer. +* If the *number* argument is already an even integer, EVEN returns it unchanged. +* Since zero is considered an even number, the EVEN function returns 0 when *number* is 0. + +### Returned value +EVEN returns a [number](/features/value-types#numbers) that is the nearest even integer, rounded away from zero. + +### Error conditions +* In common with many other IronCalc functions, EVEN propagates errors that are found in its argument. +* If no argument, or more than one argument, is supplied, then EVEN returns the [`#ERROR!`](/features/error-types.md#error) error. +* If the value of the *number* argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then EVEN returns the [`#VALUE!`](/features/error-types.md#value) error. + + + + +## Links +* For more information about even and odd numbers, visit Wikipedia's [Parity](https://en.wikipedia.org/wiki/Parity_(mathematics)) page. +* See also IronCalc's [ODD](/functions/math_and_trigonometry/odd) function. +* Visit Microsoft Excel's [EVEN function](https://support.microsoft.com/en-us/office/even-function-197b5f06-c795-4c1e-8696-3c3b8a646cf9) page. +* Both [Google Sheets](https://support.google.com/docs/answer/3093409) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/EVEN) provide versions of the EVEN function. \ No newline at end of file diff --git a/docs/src/functions/math_and_trigonometry/odd.md b/docs/src/functions/math_and_trigonometry/odd.md index 7348500..5f4b5f1 100644 --- a/docs/src/functions/math_and_trigonometry/odd.md +++ b/docs/src/functions/math_and_trigonometry/odd.md @@ -4,9 +4,41 @@ outline: deep lang: en-US --- -# ODD +# ODD function -::: warning -🚧 This function is not yet available in IronCalc. -[Follow development here](https://github.com/ironcalc/IronCalc/labels/Functions) -::: \ No newline at end of file +## Overview +ODD is a function of the Math and Trigonometry category that rounds a number up (away from zero) to the nearest odd integer. + +## Usage +### Syntax +**ODD(number) => odd** + +### Argument descriptions +* *number* ([number](/features/value-types#numbers), required). The number that is to be rounded to the nearest odd integer. + +### Additional guidance +* ODD rounds away from zero, meaning: + * Positive numbers are rounded up to the next odd integer. + * Negative numbers are rounded down (toward negative infinity) to the next odd integer. +* If the *number* argument is already an odd integer, ODD returns it unchanged. +* Since zero is considered an even number, the ODD function returns 1 when *number* is 0. + +### Returned value +ODD returns a [number](/features/value-types#numbers) that is the nearest odd integer, rounded away from zero. + +### Error conditions +* In common with many other IronCalc functions, ODD propagates errors that are found in its argument. +* If no argument, or more than one argument, is supplied, then ODD returns the [`#ERROR!`](/features/error-types.md#error) error. +* If the value of the *number* argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then ODD returns the [`#VALUE!`](/features/error-types.md#value) error. + + + + +## Links +* For more information about even and odd numbers, visit Wikipedia's [Parity](https://en.wikipedia.org/wiki/Parity_(mathematics)) page. +* See also IronCalc's [EVEN](/functions/math_and_trigonometry/even) function. +* Visit Microsoft Excel's [ODD function](https://support.microsoft.com/en-us/office/odd-function-deae64eb-e08a-4c88-8b40-6d0b42575c98) page. +* Both [Google Sheets](https://support.google.com/docs/answer/3093499) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/ODD) provide versions of the ODD function. \ No newline at end of file diff --git a/xlsx/tests/calc_tests/EVEN_ODD.xlsx b/xlsx/tests/calc_tests/EVEN_ODD.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4ffe6e30f0104bf11fc9b559a929177a4bd4db49 GIT binary patch literal 11185 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 I)B%A11KD1$2><{9 literal 0 HcmV?d00001