From 84a572aabf092a799a81e065d79caa88fdf46ef3 Mon Sep 17 00:00:00 2001 From: "holyfoot/hf@mysql.com/hfmain.(none)" <> Date: Mon, 21 May 2007 22:22:47 +0500 Subject: [PATCH] Bug #27984 Long Decimal Maths produces truncated results. decimal_round failed to perform a correct rounding of a decimal number if its first nine digits were '9'. It just sets those digits to 0. --- mysql-test/r/type_newdecimal.result | 3 +++ mysql-test/t/type_newdecimal.test | 5 +++++ strings/decimal.c | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index cbcab126439..92a5e4fc39c 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1465,4 +1465,7 @@ Error 1264 Out of range value adjusted for column 'cast(a as DECIMAL(3,2))' at r Error 1264 Out of range value adjusted for column 'cast(a as DECIMAL(3,2))' at row 1 Error 1264 Out of range value adjusted for column 'cast(a as DECIMAL(3,2))' at row 1 Error 1264 Out of range value adjusted for column 'cast(a as DECIMAL(3,2))' at row 1 +SELECT 1.000000000000 * 99.999999999998 / 100 a,1.000000000000 * (99.999999999998 / 100) b; +a b +0.9999999999999800000000000000 0.9999999999999800000000000000 End of 5.0 tests diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index a7906be79d4..3a62db1bfd7 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1149,4 +1149,9 @@ select cast(a as DECIMAL(3,2)), count(*) UNION select 12.1234 ) t group by 1; +# +# Bug #27984 Long Decimal Maths produces truncated results +# + +SELECT 1.000000000000 * 99.999999999998 / 100 a,1.000000000000 * (99.999999999998 / 100) b; --echo End of 5.0 tests diff --git a/strings/decimal.c b/strings/decimal.c index 1ae75167794..f1f02f3a071 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1517,9 +1517,10 @@ decimal_round(decimal_t *from, decimal_t *to, int scale, dec1 *p0= buf0+intg0+max(frac1, frac0); dec1 *p1= buf1+intg1+max(frac1, frac0); - to->buf[0]= 0; while (buf0 < p0) *(--p1) = *(--p0); + if (unlikely(intg1 > intg0)) + to->buf[0]= 0; intg0= intg1; buf0=to->buf;