[gnumeric] ROUND: consider some edge cases.



commit bc74821aa445240ac8996d67eb35bfe50b50506f
Author: Morten Welinder <terra gnome org>
Date:   Fri Aug 19 19:47:05 2022 -0400

    ROUND: consider some edge cases.

 NEWS                        |  1 +
 plugins/fn-math/ChangeLog   |  4 ++++
 plugins/fn-math/functions.c | 19 ++++++++++++-------
 3 files changed, 17 insertions(+), 7 deletions(-)
---
diff --git a/NEWS b/NEWS
index 5a95b92d4..72ef8611e 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Morten:
        * Fix problem with xlsx number format 14.
        * Fix problems with complex number rendering.  [#638]
        * Fix near-denormal parsing case.  [#656]
+       * Fix midly crazy ROUND edge cases.  [#661]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.52
diff --git a/plugins/fn-math/ChangeLog b/plugins/fn-math/ChangeLog
index b20a24b34..5a72955a8 100644
--- a/plugins/fn-math/ChangeLog
+++ b/plugins/fn-math/ChangeLog
@@ -1,3 +1,7 @@
+2022-08-19  Morten Welinder  <terra gnome org>
+
+       * functions.c (gnumeric_round): Handle some edge cases.  See #661.
+
 2022-04-18  Morten Welinder <terra gnome org>
 
        * Release 1.12.52
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index a0077f726..f2ea75724 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -2293,14 +2293,19 @@ gnumeric_round (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        gnm_float digits = argv[1] ? value_get_as_float (argv[1]) : 0;
 
        if (digits >= 0) {
-               if (digits <= GNM_MAX_EXP) {
-                       gnm_float p10 = gnm_pow10 ((int)digits);
-                       number = gnm_fake_round (number * p10) / p10;
-               }
+               gnm_float p10 = (digits <= INT_MAX
+                                ? gnm_pow10 ((int)digits)
+                                : gnm_pinf);
+               gnm_float y = number * p10;
+               if (gnm_finite (y))
+                       number = gnm_fake_round (y) / p10;
+               else
+                       ; // nothing -- keep number
        } else {
-               if (digits >= GNM_MIN_EXP) {
-                       /* Keep p10 integer.  */
-                       gnm_float p10 = gnm_pow10 ((int)-digits);
+               gnm_float p10 = (-digits <= INT_MAX
+                                ? gnm_pow10 ((int)-digits)
+                                : gnm_pinf);
+               if (gnm_finite (p10)) {
                        number = gnm_fake_round (number / p10) * p10;
                } else
                        number = 0;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]