使用Perl拆分浮点数

问题描述 投票:4回答:4

为什么我使用拆分会失去精度?我的目标是获得所有部分的小数部分。

$a = 123456789.123456789;
@b = split(/\./, $a);
$baseDec = "." . $b[1];

上面给出了$ baseDec == .123457

但这给出了正确的精度:这是正确的方法吗?更正:这给了同样糟糕的精确度!我没有正确测试代码。抱歉!

$a = 123456789.123456789;
@b = split(/\./, $a);
$baseInt = $b[0];
$baseDec = $a - $baseInt;

我应该使用Math :: BigFloat吗?

编辑:$ a应该是一个字符串$a = "123456789.123456789";然后原始代码工作。直到我弄清楚如何使我的Perl与longdouble一起工作,我无法测试原始问题。答案似乎是我失去了精度,因为$ a存储在一个double(52位~15位十进制数字,如下面的@Ben所述)。 print $a123456789.123457

perl split floating-point precision
4个回答
3
投票

如果您要将其视为字符串,请一直这样做。你不会在没有引用的情况下分配字符串,对吧?

my $a = "123456789.123456789";

4
投票

你失去了精度,因为123456789.123456789是一个数字文字,默认情况下,Perl编译器存储在double(52位,~15位十进制数字)$a。接下来,当@b = split(/\./, $a);运行时,$a被隐式强制成一个字符串才能成为split

如果你的Perl被编译为使用longdoubles(参见:perl -V:uselongdoubleperl -V:doublesize),则数字文字将用80位(~21个十进制数字)和字符串强制表示。


2
投票

你可以使用int

 $a = 123456789.123456789;
 $baseDec = $a - int($a);

1
投票

您可以使用sprintf获取它:

my $a = 123456789.123456789;
my @b = split(/\./, sprintf("%.8f",$a));
my $baseDec = "." . $b[1];
print $baseDec;
© www.soinside.com 2019 - 2024. All rights reserved.