ColdFusion 圆形功能 [英] ColdFusion Round function

查看:13
本文介绍了ColdFusion 圆形功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我遇到了意外的行为或对 ColdFusion 9、10、11 的知识缺乏了解,这是我的场景

Today I come across unexpected behavior or lack of knowledge with ColdFusion 9,10,11 Round function here is my scenario

Round(28.5) ---> 预期结果为 29
Round(0.285*100) ---> 结果是 28 不是预期的
Round(precisionEvaluate(0.285*100)) ---> 结果是 29 使用precisionEvaluate!
Round(Evaluate(0.285*100)) ---> 使用 Evaluate 的结果是 29!
这不是大十进制,为什么我需要对数字使用precisionEvaluate 或Evaluate?

在进一步的研究中,我发现了更有趣的行为
Round(0.285*100) 结果是 28 --WHY?我期待 29-- !
Round(0.295*100) 结果为 30 ---- 正确!
Round(0.275*100) 结果为 28 ---- 正确!
Round(0.185*100) 结果为 19 ---- 正确!
Round(0.385*100) 结果是 39 ---- 正确!

Round(28.5) ---> result is 29 expected
Round(0.285*100) ---> result is 28 not expected
Round(precisionEvaluate(0.285*100)) ---> result is 29 using precisionEvaluate!
Round(Evaluate(0.285*100)) ---> result is 29 using Evaluate!
This is not big decimal, why I would need to use precisionEvaluate or Evaluate on a number?

On farther research I found more interesting behavior
Round(0.285*100) result is 28 --WHY? I'm expecting 29-- !
Round(0.295*100) result is 30 ---- Correct !
Round(0.275*100) result is 28 ---- Correct !
Round(0.185*100) result is 19 ---- Correct !
Round(0.385*100) result is 39 ---- Correct !

推荐答案

这不是十进制数的精度,而是底层浮点数在 Java 中的存储方式.这表明:

It's not the precision of the decimal numbers, it's how the underlying floats are stored in Java. This demonstrates:

<cfoutput>
<cfloop array="#[0.275,0.285,0.295]#" index="s">
#s.getClass().getName()#
<cfset f1 = s + 0>
#f1.getClass().getName()#
#f1.toString()#
<cfset f2 = f1*100>
#f2.toString()#
#round(f2)#<br>
</cfloop>
</cfoutput>

输出:

java.lang.String java.lang.Double 0.275 27.500000000000004 28

java.lang.String java.lang.Double 0.275 27.500000000000004 28

java.lang.String java.lang.Double 0.285 28.499999999999996 28

java.lang.String java.lang.Double 0.285 28.499999999999996 28

java.lang.String java.lang.Double 0.295 29.5 30

java.lang.String java.lang.Double 0.295 29.5 30

我只能假设在执行 <cfset f1 = s + 0> 时,CF 在从字符串转换为浮点数时使用更好的精度,因为那里没有狡猾的舍入.然而,在执行乘法步骤后,我们得到了一个准确度错误.28.5 最终略低于 28.5,因此舍入到 28 而不是 29.这只是一个二进制分数算术问题.

I can only assume under the hood CF uses better precision when converting from a string to a float when performing <cfset f1 = s + 0> as there's no dodgy rounding there. However having performed the multiplication step we're getting an accuracy error bleeding in. 28.5 ends up being just shy of 28.5, so rounds to 28 not 29. It's just a binary fraction arithmetic issue.

顺便说一句,0.285 没有什么特别之处.许多数字也受到类似影响(看看从 0.005 到 5.05 的范围).你只是碰巧挑选了一堆不是的(除了 0.285).

BTW, there's nothing special about 0.285. A lot of numbers are similarly effected (have a look at the range from 0.005 to 5.05). You just happened to pick a bunch that aren't (other than 0.285).

这篇关于ColdFusion 圆形功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆