Loading mysql-test/r/func_math.result +15 −0 Original line number Diff line number Diff line Loading @@ -203,3 +203,18 @@ NULL Warnings: Error 1365 Division by 0 set sql_mode=''; select round(111,-10); round(111,-10) 0 select round(-5000111000111000155,-1); round(-5000111000111000155,-1) -5000111000111000160 select round(15000111000111000155,-1); round(15000111000111000155,-1) 15000111000111000160 select truncate(-5000111000111000155,-1); truncate(-5000111000111000155,-1) -5000111000111000150 select truncate(15000111000111000155,-1); truncate(15000111000111000155,-1) 15000111000111000150 mysql-test/t/func_math.test +14 −0 Original line number Diff line number Diff line Loading @@ -141,3 +141,17 @@ select log(2,-1); select log(-2,1); set sql_mode=''; # # Bug #8461 truncate() and round() return false results 2nd argument negative. # # round(a,-b) log_10(b) > a select round(111,-10); # round on bigint select round(-5000111000111000155,-1); # round on unsigned bigint select round(15000111000111000155,-1); # truncate on bigint select truncate(-5000111000111000155,-1); # truncate on unsigned bigint select truncate(15000111000111000155,-1); sql/item_func.cc +18 −16 Original line number Diff line number Diff line Loading @@ -1863,28 +1863,30 @@ longlong Item_func_round::int_op() return value; // integer have not digits after point abs_dec= -dec; double tmp; /* 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 */ volatile double tmp2; longlong tmp; tmp= (abs_dec < array_elements(log_10) ? log_10[abs_dec] : pow(10.0, (double) abs_dec)); if(abs_dec >= array_elements(log_10_int)) return 0; tmp= log_10_int[abs_dec]; if (truncate) { if (unsigned_flag) tmp2= floor(ulonglong2double(value)/tmp)*tmp; else if (value >= 0) tmp2= floor(((double)value)/tmp)*tmp; value= (ulonglong(value)/tmp)*tmp; else tmp2= ceil(((double)value)/tmp)*tmp; value= (value/tmp)*tmp; } else tmp2= rint(((double)value)/tmp)*tmp; return (longlong)tmp2; { if (unsigned_flag) value= ((ulonglong(value)+(tmp>>1))/tmp)*tmp; else if ( value >= 0) value= ((value+(tmp>>1))/tmp)*tmp; else value= ((value-(tmp>>1))/tmp)*tmp; } return value; } Loading Loading
mysql-test/r/func_math.result +15 −0 Original line number Diff line number Diff line Loading @@ -203,3 +203,18 @@ NULL Warnings: Error 1365 Division by 0 set sql_mode=''; select round(111,-10); round(111,-10) 0 select round(-5000111000111000155,-1); round(-5000111000111000155,-1) -5000111000111000160 select round(15000111000111000155,-1); round(15000111000111000155,-1) 15000111000111000160 select truncate(-5000111000111000155,-1); truncate(-5000111000111000155,-1) -5000111000111000150 select truncate(15000111000111000155,-1); truncate(15000111000111000155,-1) 15000111000111000150
mysql-test/t/func_math.test +14 −0 Original line number Diff line number Diff line Loading @@ -141,3 +141,17 @@ select log(2,-1); select log(-2,1); set sql_mode=''; # # Bug #8461 truncate() and round() return false results 2nd argument negative. # # round(a,-b) log_10(b) > a select round(111,-10); # round on bigint select round(-5000111000111000155,-1); # round on unsigned bigint select round(15000111000111000155,-1); # truncate on bigint select truncate(-5000111000111000155,-1); # truncate on unsigned bigint select truncate(15000111000111000155,-1);
sql/item_func.cc +18 −16 Original line number Diff line number Diff line Loading @@ -1863,28 +1863,30 @@ longlong Item_func_round::int_op() return value; // integer have not digits after point abs_dec= -dec; double tmp; /* 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 */ volatile double tmp2; longlong tmp; tmp= (abs_dec < array_elements(log_10) ? log_10[abs_dec] : pow(10.0, (double) abs_dec)); if(abs_dec >= array_elements(log_10_int)) return 0; tmp= log_10_int[abs_dec]; if (truncate) { if (unsigned_flag) tmp2= floor(ulonglong2double(value)/tmp)*tmp; else if (value >= 0) tmp2= floor(((double)value)/tmp)*tmp; value= (ulonglong(value)/tmp)*tmp; else tmp2= ceil(((double)value)/tmp)*tmp; value= (value/tmp)*tmp; } else tmp2= rint(((double)value)/tmp)*tmp; return (longlong)tmp2; { if (unsigned_flag) value= ((ulonglong(value)+(tmp>>1))/tmp)*tmp; else if ( value >= 0) value= ((value+(tmp>>1))/tmp)*tmp; else value= ((value-(tmp>>1))/tmp)*tmp; } return value; } Loading