summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-01-16 20:16:35 +0100
committerSergei Golubchik <sergii@pisem.net>2012-01-16 20:16:35 +0100
commit38e3ae155db08ab2e9e5c267f05f89bec0542b33 (patch)
tree7289bbef1ba3f495aa5c7cdb7d0a3f993a5bbc80 /sql/item_func.cc
parentc56483d972d023105fbcb0f47af0042ee092657c (diff)
parented1ba992c1d3c3ecbe6a2769c51ceb5d27606d3b (diff)
downloadmariadb-git-38e3ae155db08ab2e9e5c267f05f89bec0542b33.tar.gz
mysql-5.5 merge
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc18
1 files changed, 12 insertions, 6 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 034ffbea344..92431a552c4 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2476,25 +2476,31 @@ double my_double_round(double value, longlong dec, bool dec_unsigned,
/*
tmp2 is here to avoid return the value with 80 bit precision
This will fix that the test round(0.1,1) = round(0.1,1) is true
+ Tagging with volatile is no guarantee, it may still be optimized away...
*/
volatile double tmp2;
tmp=(abs_dec < array_elements(log_10) ?
log_10[abs_dec] : pow(10.0,(double) abs_dec));
+ // Pre-compute these, to avoid optimizing away e.g. 'floor(v/tmp) * tmp'.
+ volatile double value_div_tmp= value / tmp;
+ volatile double value_mul_tmp= value * tmp;
+
if (dec_negative && my_isinf(tmp))
- tmp2= 0;
- else if (!dec_negative && my_isinf(value * tmp))
+ tmp2= 0.0;
+ else if (!dec_negative && my_isinf(value_mul_tmp))
tmp2= value;
else if (truncate)
{
- if (value >= 0)
- tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp;
+ if (value >= 0.0)
+ tmp2= dec < 0 ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp;
else
- tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp;
+ tmp2= dec < 0 ? ceil(value_div_tmp) * tmp : ceil(value_mul_tmp) / tmp;
}
else
- tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp;
+ tmp2=dec < 0 ? rint(value_div_tmp) * tmp : rint(value_mul_tmp) / tmp;
+
return tmp2;
}