| 676 | } |
| 677 | |
| 678 | double my_double_round(double value, longlong dec, bool dec_unsigned, |
| 679 | bool truncate) |
| 680 | { |
| 681 | double tmp; |
| 682 | bool dec_negative= (dec < 0) && !dec_unsigned; |
| 683 | ulonglong abs_dec= dec_negative ? -dec : dec; |
| 684 | /* |
| 685 | tmp2 is here to avoid return the value with 80 bit precision |
| 686 | This will fix that the test round(0.1,1) = round(0.1,1) is true |
| 687 | Tagging with volatile is no guarantee, it may still be optimized away... |
| 688 | */ |
| 689 | volatile double tmp2; |
| 690 | |
| 691 | tmp=(abs_dec < array_elements(log_10) ? |
| 692 | log_10[abs_dec] : pow(10.0,(double) abs_dec)); |
| 693 | |
| 694 | // Pre-compute these, to avoid optimizing away e.g. 'floor(v/tmp) * tmp'. |
| 695 | volatile double value_div_tmp= value / tmp; |
| 696 | volatile double value_mul_tmp= value * tmp; |
| 697 | |
| 698 | if (dec_negative && my_isinf(tmp)) |
| 699 | tmp2= 0.0; |
| 700 | else if (!dec_negative && my_isinf(value_mul_tmp)) |
| 701 | tmp2= value; |
| 702 | else if (truncate) |
| 703 | { |
| 704 | if (value >= 0.0) |
| 705 | tmp2= dec < 0 ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp; |
| 706 | else |
| 707 | tmp2= dec < 0 ? ceil(value_div_tmp) * tmp : ceil(value_mul_tmp) / tmp; |
| 708 | } |
| 709 | else |
| 710 | tmp2=dec < 0 ? rint(value_div_tmp) * tmp : rint(value_mul_tmp) / tmp; |
| 711 | |
| 712 | return tmp2; |
| 713 | } |
| 714 | |
| 715 | void Item_func_locate::print(String *str, enum_query_type query_type) |
| 716 | { |