Dav*_*mov 6 mysql sql floating-point numbers
MySQL版本是5.66.22
当我ROUND对存储在varchar中的十进制数字使用函数时,我看到所有.5数字的奇怪行为
Select round(0.5)
1
Select round('0.5')
0
Select round('26.5' + 0.00)
26
Run Code Online (Sandbox Code Playgroud)
但
Select round(1.5)
2
Select round('1.5')
2
Select round(0.55, 1)
0.6
Select round('0.55', 1)
0.6
Run Code Online (Sandbox Code Playgroud)
我在Oracle DB(12c)中检查了ROUND函数,它按预期工作
Select round('0.5') from dual
1
Select round(0.5) from dual
1
Run Code Online (Sandbox Code Playgroud)
有人知道如何解释吗?
所描述的mysql round()函数行为在应用程序中引起“取整”问题。为了解决这个问题,我使用:
Select round (CAST('0.5' AS DECIMAL(10,2)))
1
Run Code Online (Sandbox Code Playgroud)
我知道将数字存储在varchar中是不好的设计,但是此应用程序是很久以前编写的,现在没有人想要重构代码
有趣的。该行为可以解释如下:
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 | |
+----------------+--------------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)
2)如手册中所述:
该
ROUND()函数根据其参数是精确的还是近似的进行不同的舍入:
对于精确值数字,
ROUND()使用“四舍五入”规则:小数部分为 0.5 或更大的值如果为正则向上舍入到下一个整数,如果为负则向下舍入到下一个整数。(换句话说,它从零开始舍入。)小数部分小于 0.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 |
+------+-------------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
您的解决方案,将数字字符串显式转换为DECIMAL,是正确的。
| 归档时间: |
|
| 查看次数: |
1010 次 |
| 最近记录: |