mysql round()函数,用于存储在字符串中的十进制数

z4iuyo4d  于 2021-06-23  发布在  Mysql
关注(0)|答案(1)|浏览(376)

mysql版本是5.66.22
当我使用 ROUND 函数的十进制数存储在varchar我看到奇怪的行为为所有.5数字

Select round(0.5)
1

Select round('0.5')
0

Select round('26.5' + 0.00)
26

但是

Select round(1.5)
2

Select round('1.5')
2

Select round(0.55, 1)
0.6

Select round('0.55', 1)
0.6

我检查了oracledb(12c)中的round函数,它按预期工作

Select round('0.5') from dual 
1

Select round(0.5) from dual 
1

有人知道怎么解释吗?
所描述的mysql round()函数行为导致应用程序中出现“舍入”问题。为了解决我使用的问题:

Select round (CAST('0.5' AS DECIMAL(10,2)))
1

我知道在varchar中存储数字是个糟糕的设计,但是这个应用程序是很久以前编写的,现在没有人想重构代码

nr9pn0ug

nr9pn0ug1#

很有趣。这种行为可以解释如下:
1) mysql在数字上下文(ref)中使用时将字符串转换为浮点值:

CREATE TABLE test AS (
    SELECT 0.5, '0.5' * 1 AS str_to_numeric
);

DESCRIBE test;

+----------------+--------------+------+-----+---------+-------+
| Field          | Type         | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| 0.5            | decimal(2,1) | NO   |     | 0.0     |       |
| str_to_numeric | double       | NO   |     | 0       |       |
+----------------+--------------+------+-----+---------+-------+

2) 如手册所述:
舍入行为
这个 ROUND() 函数根据其参数是精确的还是近似的而不同:
对于精确的数值, ROUND() 使用“向上取整”规则:分数部分为.5或更大的值如果为正,则向上取整为下一个整数;如果为负,则向下取整为下一个整数(换言之,它从零取整。)分数部分小于.5的值如果为正,则向下舍入到下一个整数;如果为负,则向上舍入到下一个整数。
对于近似值数字,结果取决于c库。在许多系统上,这意味着 ROUND() 使用“四舍五入到最接近的偶数”规则:带有任何小数部分的值四舍五入到最接近的偶数整数。
下面是一些说明round函数最终行为的测试:

CREATE TABLE test(
   fix DECIMAL(10,2),
   arb DOUBLE
);

INSERT INTO test(fix, arb) VALUES
    (0.5, 0.5),
    (1.5, 1.5),
    (2.5, 2.5),
    (3.5, 3.5);

SELECT fix, ROUND(fix) fix_roundex, arb, ROUND(arb) arb_rounded
FROM test

+------+-------------+------+-------------+
| fix  | fix_roundex | arb  | arb_rounded |
+------+-------------+------+-------------+
| 0.50 |           1 |  0.5 |           0 |
| 1.50 |           2 |  1.5 |           2 |
| 2.50 |           3 |  2.5 |           2 |
| 3.50 |           4 |  3.5 |           4 |
+------+-------------+------+-------------+

您的解决方案,显式地将数字字符串 DECIMAL ,是正确的。

相关问题