今天我遇到了意想不到的行为或缺乏对 ColdFusion 9,10,11 Round 函数的了解,这是我的场景
Round(28.5) ---> 预期结果为 29
Round(0.285*100) ---> 结果不是预期的 28
Round( precisionEvaluate(0.285*100)) ---> 使用 precisionEvaluate 结果是 29!
Round(Evaluate(0.285*100)) ---> 使用 Evaluate 结果是 29!
这不是大十进制,为什么我需要对数字使用 precisionEvaluate 或 Evaluate ?
在进一步的研究中,我发现了更有趣的行为
Round(0.285*100) 结果是 28 --为什么?我期待29--!
Round(0.295*100) 结果是 30 ---- 正确!
Round(0.275*100) 结果是 28 ---- 正确!
Round(0.185*100) 结果是 19 ---- 正确!
Round(0.385*100) 结果是 39 ---- 正确!
0.285*100 有什么大不了的?
这不是十进制数的精度,而是底层浮点数在 Java 中的存储方式。这表明:
<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>
Output:
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.295 29.5 30
我只能假设在执行时从字符串转换为浮点时 CF 使用更好的精度<cfset f1 = s + 0>
因为那里没有狡猾的四舍五入。然而,在执行乘法步骤后,我们遇到了精度错误。28.5 最终略低于 28.5,因此四舍五入为 28,而不是 29。这只是一个二进制分数算术问题。
顺便说一句,0.285 没有什么特别的。许多数字都会受到类似的影响(看看从 0.005 到 5.05 的范围)。您只是碰巧选择了一堆不是的(0.285 除外)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)