ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL中Round函数没有四舍五入

2021-07-05 15:32:22  阅读:285  来源: 互联网

标签:四舍五入 Round CAST num SQL 100 ROUND select


先来看下面SQL执行结果:

select cast(CAST(ROUND(nvl(0.987689,0)*100,2) AS DECIMAL(4,2)) AS STRING) num;
select cast(CAST(ROUND(nvl(0.804889,0)*100,2) AS DECIMAL(4,2)) AS STRING) num;
select round(0.8048892988929889*100,2) num;
select cast(CAST(ROUND(nvl(0.805889,0)*100,2) AS DECIMAL(4,2)) AS STRING) num;
select CAST(ROUND(cast(nvl(0.8038892988929889,0) as DECIMAL(7,5))*100,2) as string) num;
select CAST(ROUND(cast(nvl(0.8048892988929889,0) as DECIMAL(7,5))*100,2) as string) num;

执行结果依次为:

98.77
80.48
80.49
80.59
80.49

注:使用的数据库是impala

有图有真相

问题:

0.987689乘100后(98.7689)保留两位小数,可以四舍五入,结果为:98.77;

0.805889乘100后(80.5889)保留两位小数,可以四舍五入,结果为:80.59;

0.803889乘100后(80.3889)保留两位小数,可以四舍五入,结果为:80.39;

但0.804889乘100后(80.4889)保留两位小数,没有四舍五入,结果为:80.48。

知道了问题,现在分析一下原因:

为什么我们在写sql使用round函数四舍五入时,0.804889乘100后保留两位小数,明明后面是8可以进位反而舍掉了呢?

原因一:

在于“四舍六入五成双”原则(来源于百度百科)
对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是“四舍六入五成双”,也即“4舍6入5凑偶”,这里“四”是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:
(1)5前为奇数,舍5入1;
(2)5前为偶数,舍5不进。

我理解的这里的“5”是指代比5大的数字。

上面这些的意思就是:

80.3889这里的8前面是3(奇数),所以舍8入1,就是9;

80.5889这里的8前面是5(奇数),所以舍8入1,就是9;

80.4889这里的8前面是4(偶数),所以舍8不进,还是8;

到这里还没有完,聪明的你会发现:

为什么这两个执行的结果不一致。

原因二:

查看了官方文档的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 函数会使用“取最近的偶数”的规则)
在计算机的计算领域里,包括JAVA里的double,float都不算是精准的计算类型,一般都用decimal进行精准计算,所以Round的计算就默认的走了第二条规则。

解决方案:
先采用CAST函数,用于将某种数据类型的表达式显式转换为另一种数据类型decimal。然后再ROUND函数。

执行结果如下:

愿你遍历山河 仍觉人间值得

标签:四舍五入,Round,CAST,num,SQL,100,ROUND,select
来源: https://blog.csdn.net/Allenzyg/article/details/118489492

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有