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,
/*
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;
}
......
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