免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1733 | 回复: 0
打印 上一主题 下一主题

再说精度-用于显示的数字出现精度问题的处理-(Perl/Java) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-12-21 21:32 |只看该作者 |倒序浏览

再说精度-用于显示的数字出现精度问题的处理-(Perl/Java)
描述
1. 昨天在ChinaUnix上看见一个问题(Perl):
$ad=1.25 - 1.24;        #$ad答案是0.01
$ad = 2.25 - 2.24;        #$ad答案应也是0.01,但出现的答案是0.009999999999999979...
为什麽?怎样更正? 谢
2. 前段时间刚做完的一个TOYOTA的J2EE项目也遇到类似问题:
    把12个字段的字符串转成float再相加,每个字段都是#.##的格式,结果应该等于12.00,可实际是11.9999....,插入到Text里时还出现了越界。
问题
1. 精度:浮点数不能准确的表示
2. 结果的用途:用于计算的数值出现误差时,可能导致计算结果出现很大偏差,即使不会有太大的影响最好也不要冒险;数值是用于显示时,并不一定要处理float使之符合要求,可以尝试处理字符串。本文针对后一种情况。
3. 四舍五入:我简单的翻了一下Perl的函数库,没找到round函数。
解决办法
       因为结果是用来显示的,所以并不一定要使float完全符合#.##的形式,可以考虑处理字符串。
      由于结果应该符合#.##的形式,也就是说就四舍五入到0.01,但round()[JAVA]和int()[Perl]只能处理整数,所以先将数值乘以100,然后转换为字符串。判断字符串长度,当长度大于1时,在length-2的位置插入“.”,否则从0位置插入“0.0”。
$a = 2.25 - 2.24;                # $a = 0.00999999999999979
$a = $a * 100 + 0.5;        # $a = 1.49999999999998
                                                # prepare for round off
$a = int( $a );                        # $a = 1;
# now, we got the int value 100 times more than
# the value wanted.
$a = "0.0" . $a
                                                # $a = 0.01
# here is the value we wanted. But the value must
# less than 10. If we want deal with the value
# more than 10, we must judging length of the
# value and whether append it "0.0"
# in the front or insert a "." into
# the string.
print $a;
输出:0.01
参考
1.MSDN对浮点数精度的描述
《为何浮点数可能丢失精度》
      浮点十进制值通常没有完全相同的二进制表示形式。这是 CPU 所采用的浮点数据表示形式的副作用。为此,可能会经历一些精度丢失,并且一些浮点运算可能会产生意外的结果。
导致此行为的原因是下面之一:
      十进制数的二进制表示形式可能不精确。
      使用的数字之间类型不匹配(例如,混合使用浮点型和双精度型)。
      为解决此行为,大多数程序员或是确保值比需要的大或者小,或是获取并使用可以维护精度的二进制编码的十进制 (BCD) 库。
      浮点值的二进制表示形式影响浮点计算的精度和准确性。Microsoft Visual C++ 使用 IEEE 浮点格式。
2 四舍五入的算法
      四舍五入的算法处理整数,先将数值加0.5,再取得整数部分。
      Java中的Math类有round函数,可我在Perl中没找到(可能有)。我想Perl主要是针对字符串处理,也许没有这方面的函数。所幸在Perl中找到int($) 函数来截断整数。
所以,在Perl中可以这样做:
$value = int( $old + 0.5 );
在Java中直接使用Math.round()。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/5033/showart_62809.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP