Perl 数字运算的疑问

2013-09-25 22:48:09 +08:00
 18m
#! /usr/bin/perl
$x = 4.5232 - 4.5111;
$y = 0.5232 - 0.5111;
print "$x\n$y\n";


$x = 0.0121000000000002
$y = 0.0121

为什么会产生这样的差别? $x的0.0000000000000002 来自哪里? 我该怎么得到正确的答案?
谢谢
3459 次点击
所在节点    问与答
7 条回复
11138
2013-09-25 22:52:49 +08:00
加上:
use bignum;

或者用 Math::BigFloat 模块解决(建议)。
18m
2013-09-25 22:54:24 +08:00
非常感谢,已经解决。
我再研究一下为什么会产生这个问题。
polythene
2013-09-25 23:33:46 +08:00
那是因为计算机本身是无法精确的表示一个浮点数的,这不是perl的问题,而是计算机本身结构的问题,你用python, ruby, c都会得到同样的结果。
18m
2013-09-25 23:52:06 +08:00
@polythene
@11138
再谢
假如我用 Math::BigFloat 的话应该如何做呢? cpan的说明我没看懂。我不是学计算机的,现在只是想用perl处理一堆数据,搞不明白浮点小数在计算机里面的内部机理也不想去研究太深。
polythene
2013-09-26 00:20:08 +08:00
printf("%.4f\n", 4.5232-4.5111);
=>0.0121

具体请谷之"perl print 浮点数"。
11138
2013-09-26 00:25:38 +08:00
use Math::BigFloat;
my $a1 = 2.25;
my $a2 = 2.24;
$a1 = Math::BigFloat->new($a1);
$a2 = Math::BigFloat->new($a2);
my $a3 = $a1 - $a2;
print "\$a3 = $a3\n";

另外,我不建议直接加:
use bignum;
是因为它与timelocal有可能出现冲突(其它的没遇过),导致结果不对。
18m
2013-09-26 01:23:42 +08:00
谢谢 @polythene
利用printf 对于我目前的数据来说精度足够了,而且性能好很多,我目前就按照这样的方法做了。
Perl的Math::BigFloat 性能很差。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/83693

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX