perl - 如何在 Perl 中强制 long double

标签 perl printf precision long-double

在进行算术运算或尝试打印(调试)这么大的数字时,我会失去精度:
1234567890.123456789

我认为我的问题在于 $d(算术结果)和 $e 的格式化打印。
我怎样才能强制长 double ?我的 Perl 版本(SUN 上的 5.8.4)说这是可能的。
sprintf 有一个长 double 的大小选项(q 或 L 或 ll),但我还没有弄清楚如何使用它,也不知道它是否适用于 printf。

编辑: 我添加了 BigFloat,它有效!但我仍然想强制长 double 。

尝试添加 1234567890 + 0.123456789
并减去 1234567890 - 0.123456789。

use Config;
use Math::BigFloat;
$a = 1234567890;
$b = 123456789;
$c = $b/1e9;                   # 0.123456789
$d = $a + $c;                  # not enough precision (32-bit or double?)
$e = sprintf("%d.%.9d",$a,$b); # combine as strings
$f = 1234567890.123456789;     # for reference (not enough precision)

# Use BigFloat to bypass lack of longdbl
$aBig = Math::BigFloat->new("$a");
$dSum = $aBig->fadd("$c");         # $dSum = $a + $c
$aBig = Math::BigFloat->new("$a"); # <-- Need a new one for every operation?
$dDif = $aBig->fsub(abs("$c"));    # $dDif = $a - $c

print "a $a\n";             # 1234567890  
print "c $c\n";             # 0.123456789
print "d=a+c $d\n";         # 1234567890.12346  <-- **Problem**
print "dSum=a+c $dSum\n";   # 1234567890.123456789  <-- Solution
print "dDif=a-c $dDif\n";   # 1234567890.876543211  <-- Solution
print "e $e\n";             # 1234567890.123456789
print "f $f\n";             # 1234567890.12346  <-- double, 52-bit, not longdbl? 
printf ("printf    e 20.9f %20.9f\n",$e);    # 1234567890.123456717 <-- **Problem**
printf ("printf dSum 20.9f %20.9f\n",$dSum); # 1234567890.123456717 <-- **Problem**
printf ("printf dSum 20s %20s\n",$dSum);     # 1234567890.123456789 
printf ("printf dDif 20.9f %20.9f\n",$dDif); # 1234567890.876543283 <-- **Problem**
printf ("printf dDif 20s %20s\n",$dDif);     # 1234567890.876543211 

print "uselongdouble $Config{uselongdouble}\n"; # empty. No long doubles by default
print "d_longdbl $Config{d_longdbl}\n";         # "define". Supports long doubles
print "size double longdbl $Config{doublesize} $Config{longdblsize}\n"; # Ans 8 16

我还使用此代码来尝试理解类型,但没有太大帮助。有没有人用它来解释这样的问题?
use Devel::Peek 'Dump';

Dump ($dSum); # Wow, it's complicated
Dump ($f);

最佳答案

Perl 有一种浮点数,称为 NV . NV 的大小是在构建 Perl 时决定的。

$ perl -V:nvsize
nvsize='8';

在 Perl 程序中也可以通过 Config 模块访问此信息。
$ perl -MConfig -E'say $Config{nvsize}'
8

大小NV Perl 构建后无法更改。

您可以强制构建 Perl 以使用 long double在构建 Perl 时 float 如下:
sh Configure -Duselongdouble ...
  -or-
perlbrew install -Duselongdouble ...
  -or-
perlbrew install --ld ...

如果你不想重建你的 perl或制作一个新的,您将需要使用一个模块。我推荐Math::LongDouble因为它提供对 native long double 的访问 float ,并且它尽可能透明地这样做。

另一种选择是使用任意精度库,例如 Math::BigFloat ,但如果您只需要 long double .

关于perl - 如何在 Perl 中强制 long double,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27933410/

相关文章:

c - 将十六进制字节转换为字符字符串

c - GCC:为什么这个 fprintf 有一个 -Wformat 警告?

c - 显示 MSB 到 LSB

java - Java 中使用 double 保持精度

sql-server - Sql Server 精度疯狂

Perl UTF-8/编码 : How to detect $str1 eq $str2 to avoid MySQL round-trip?

引擎盖下的 perl 64 位整数

Rcpp - 如何计算 rowSums 恰好为 1 的矩阵

perl - 在 perl 中比较字符串数组的最佳方法是什么

perl - cpan模块目录结构