Commit 38138943 authored by Tor Didriksen's avatar Tor Didriksen

Bug#13261955 TRUNCATE(DBL_MAX) RETURNS DBL_MAX RATHER THAN 'INF'

my_double_round(DBL_MAX, -12, ....)
should return 'inf' rather than DBL_MAX

The problem is that floor(value/tmp) * tmp
is inlined, and optimized away.

The solution seems to be to prevent inlining by pre-computing value/tmp and
storing it in a variable.

No new test case: main.type_float fails without this patch.
parent a2f757ea
...@@ -2328,25 +2328,31 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, ...@@ -2328,25 +2328,31 @@ double my_double_round(double value, longlong dec, bool dec_unsigned,
/* /*
tmp2 is here to avoid return the value with 80 bit precision 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 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; volatile double tmp2;
tmp=(abs_dec < array_elements(log_10) ? tmp=(abs_dec < array_elements(log_10) ?
log_10[abs_dec] : pow(10.0,(double) abs_dec)); 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)) if (dec_negative && my_isinf(tmp))
tmp2= 0; tmp2= 0.0;
else if (!dec_negative && my_isinf(value * tmp)) else if (!dec_negative && my_isinf(value_mul_tmp))
tmp2= value; tmp2= value;
else if (truncate) else if (truncate)
{ {
if (value >= 0) if (value >= 0.0)
tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp; tmp2= dec < 0 ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp;
else 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 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; return tmp2;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment