summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_math.result6
-rw-r--r--mysql-test/t/func_math.test7
-rw-r--r--strings/decimal.c29
3 files changed, 38 insertions, 4 deletions
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index c7674c57c8d..b7188092b41 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -146,3 +146,9 @@ drop table t1;
select round(150, 2);
round(150, 2)
150.00
+select ceil(0.09);
+ceil(0.09)
+1
+select ceil(0.000000000000000009);
+ceil(0.000000000000000009)
+1
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 03057af6911..da4b8335e07 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -84,3 +84,10 @@ drop table t1;
# Bug #10083 (round doesn't increase decimals)
#
select round(150, 2);
+
+#
+# Bug @10632 (Ceiling function returns wrong answer)
+#
+select ceil(0.09);
+select ceil(0.000000000000000009);
+
diff --git a/strings/decimal.c b/strings/decimal.c
index de64933466d..18f920badd3 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1490,11 +1490,31 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
buf1+=intg0+frac0-1;
if (scale == frac0*DIG_PER_DEC1)
{
+ int do_inc= FALSE;
DBUG_ASSERT(frac0+intg0 >= 0);
- x=buf0[1]/DIG_MASK;
- if (x > round_digit ||
- (round_digit == 5 && x == 5 && (mode == HALF_UP ||
- (frac0+intg0 > 0 && *buf0 & 1))))
+ switch (round_digit)
+ {
+ case 0:
+ {
+ dec1 *p0= buf0 + (frac1-frac0);
+ for (; p0 > buf0; p0--)
+ if (*p0)
+ {
+ do_inc= TRUE;
+ break;
+ };
+ break;
+ }
+ case 5:
+ {
+ x= buf0[1]/DIG_MASK;
+ do_inc= (x>5) || ((x == 5) &&
+ (mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
+ break;
+ };
+ default:;
+ };
+ if (do_inc)
{
if (frac0+intg0>0)
(*buf1)++;
@@ -1509,6 +1529,7 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
}
else
{
+ /* TODO - fix this code as it won't work for CEILING mode */
int pos=frac0*DIG_PER_DEC1-scale-1;
DBUG_ASSERT(frac0+intg0 > 0);
x=*buf1 / powers10[pos];