设为首页 收藏本站
查看: 973|回复: 0

[经验分享] [原]再说精度-用于显示的数字出现精度问题的处理-(Perl/Java)

[复制链接]

尚未签到

发表于 2015-12-29 09:28:50 | 显示全部楼层 |阅读模式
  
  2005年03月03日写的东西,整理了以前的博客,转到这里来。
  
  
  描述

1. 昨天在ChinaUnix上看见一个问题:

$ad=1.25 - 1.24;                  #$ad答案是0.01

#$ad答案应也是0.01,但出现的答案是0。009999999999999979...
$ad = 2.25 - 2.24;                 

为什麽?怎样更正? 谢

  
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()。


作者:basecn 发表于2010-6-3 22:03:00 原文链接
阅读:124 评论:0 查看评论

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-157805-1-1.html 上篇帖子: Perl 学习笔记 下篇帖子: [Web开发] 6款著名的开源的Web开发框架横向评测 (Perl, PHP, Python, Ruby)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表