MySQL中ROUND函数进行四舍五入操作陷阱分析

作者:Joker_Ye 时间:2024-01-15 04:02:04 

本文实例讲述了MySQL中ROUND函数进行四舍五入操作陷阱。分享给大家供大家参考,具体如下:

在MySQL中, ROUND 函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并没有预期的那样,本文将这一问题记录下来,以免大家跟我一样犯同样的错误。

问题描述

假如我们有如下一个数据表 test ,建表语句如下


CREATE TABLE test (
id int(11) NOT NULL AUTO_INCREMENT,
field1 bigint(10) DEFAULT NULL,
field2 decimal(10,0) DEFAULT NULL,
field3 int(10) DEFAULT NULL,
field4 float(15,4) DEFAULT NULL,
field5 float(15,4) DEFAULT NULL,
field6 float(15,4) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我们创建了一个名为 test 的表,出了 id 字段之外还包含了多个字段,拥有这不同的数据类型。我们向这个表中插入一条数据


INSERT INTO test (field1, field2, field3, field4, field5, field6) VALUE (100, 100, 100, 1.005, 3.5, 2.5);

插入之后表中的数据是这样的


mysql> select * from test;
+----+--------+--------+--------+--------+--------+--------+
| id | field1 | field2 | field3 | field4 | field5 | field6 |
+----+--------+--------+--------+--------+--------+--------+
| 1 |  100 |  100 |  100 | 1.0050 | 3.5000 | 2.5000 |
+----+--------+--------+--------+--------+--------+--------+
1 rowin set (0.00 sec)

如果现在我们执行下面这个SQL,你觉得结果会是什么样的呢?


SELECT
round(field1 * field4),
round(field2 * field4),
round(field3 * field4),
round(field1 * 1.005),
round(field2 * 1.005),
round(field3 * 1.005),
round(field5),
round(field6)
FROM test;

最初一直以为这样的结果肯定是都是 101 ,因为上面这六个取值结果都是对 100 * 1.005 进行四舍五入,结果肯定都是 101 才对,而后面两个肯定是 4 和 3 才对,但是最终的结果却是与设想的大相径庭


*************************** 1. row ***************************
round(field1 * field4): 100
round(field2 * field4): 100
round(field3 * field4): 100
round(field1 * 1.005): 101
round(field2 * 1.005): 101
round(field3 * 1.005): 101
   round(field5): 4
   round(field6): 2
1 rowin set (0.00 sec)

为什么会这样?

同样是100*1.005,为什么从数据库中的字段相乘得到的结果和直接字段与小数相乘得到的不一样呢?

对这个问题百思不得其解,各种百度谷歌无果。。。没办法,还得靠自己,这个时候最有用的就是官网文档了,于是查询了mysql官方文档中关于ROUND函数的部分,其中包含下面两条规则

  • For exact-value numbers, ROUND() uses the “round half up” rule(对于精确的数值, ROUND 函数使用四舍五入)

  • For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest even” rule: A value with any fractional part is rounded to the nearest even integer. (对于近似值,则依赖于底层的C函数库,在很多系统中 ROUND 函数会使用“取最近的偶数”的规则)

通过这两条规则,我们可以看出,由于我们在使用两个字段相乘的时候,最终的结果是按照 float 类型处理的,而在计算机中 float 类型不是精确的数,因此处理结果会按照第二条来,而直接整数字段与1.005这样的小数运算的结果是因为两个参与运算的值都是精确数,因此按照第一条规则计算。从 field5 和 field6 执行 ROUND 函数的结果可以明确的看确实是转换为了最近的偶数。

总结

从这个例子中可以看到,在MySQL中使用ROUND还是要非常需要注意的,特别是当参与计算的字段中包含浮点数的时候,这个时候计算结果是不准确的。

希望本文所述对大家MySQL数据库计有所帮助。

来源:https://blog.csdn.net/hj7jay/article/details/54666628

标签:MySQL,ROUND,四舍五入
0
投稿

猜你喜欢

  • python实现括号匹配的思路详解

    2023-08-24 16:50:30
  • Python如何优雅删除字符列表空字符及None元素

    2023-10-26 19:17:00
  • python实现一个点绕另一个点旋转后的坐标

    2023-04-24 19:29:24
  • 兼容低版本 IE 的 JScript 5.5 实现

    2008-07-01 12:48:00
  • Python高级架构模式知识点总结

    2023-12-19 14:36:47
  • Python3 类型标注支持操作

    2021-12-25 05:39:41
  • Vuex之理解Store的用法

    2024-05-13 09:37:33
  • JavaScript实现图片放大预览效果

    2023-08-23 02:41:17
  • 详解tensorflow载入数据的三种方式

    2023-07-22 19:35:56
  • 使用keras内置的模型进行图片预测实例

    2021-12-27 17:54:29
  • python识别图像并提取文字的实现方法

    2023-06-07 18:36:36
  • Python 如何手动编写一个自己的LRU缓存装饰器的方法实现

    2022-08-04 13:06:10
  • MyEclipse连接Mysql数据库的方法(一)

    2024-01-23 11:31:29
  • JavaScript生成二维码图片小结

    2024-05-02 16:13:16
  • 详解Python安装scrapy的正确姿势

    2023-04-04 01:38:14
  • 关于Flask 视图介绍

    2022-10-21 15:07:34
  • vue 项目代码拆分的方案

    2024-06-05 09:17:56
  • 对vue2.0中.vue文件页面跳转之.$router.push的用法详解

    2024-04-30 10:35:03
  • python二叉树类以及其4种遍历方法实例

    2023-07-25 02:22:48
  • golang实现http服务器处理静态文件示例

    2024-05-21 10:22:17
  • asp之家 网络编程 m.aspxhome.com