diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-01-16 20:16:35 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-01-16 20:16:35 +0100 |
commit | 38e3ae155db08ab2e9e5c267f05f89bec0542b33 (patch) | |
tree | 7289bbef1ba3f495aa5c7cdb7d0a3f993a5bbc80 /sql/item_func.cc | |
parent | c56483d972d023105fbcb0f47af0042ee092657c (diff) | |
parent | ed1ba992c1d3c3ecbe6a2769c51ceb5d27606d3b (diff) | |
download | mariadb-git-38e3ae155db08ab2e9e5c267f05f89bec0542b33.tar.gz |
mysql-5.5 merge
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 18 |
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; } |