从科学符号转换为十进制符号时,如何保持显示精度?

时间:2017-01-11 18:25:53

标签: perl precision

考虑以下浮动:

8.22120183514065e-05

现在显然(s)printf是标准的事情,但是%f会改变它的精确度:

printf "%f", 8.22120183514065e-05;    # 0.000082

使用任意大的精度,比如%.30f,添加额外的数字(...6505):

printf "%.30f", 8.22120183514065e-05; # 0.000082212081351406505000000000

有没有办法在不事先知道其准确精度的情况下保持科学记数法中存在的精度?

1 个答案:

答案 0 :(得分:3)

我相信你问的是如何对一个数字进行字符串化,使得字符串化具有与产生该数字的代码文字相同数量的显着数字。

那是不可能的。产生数字的代码文字中的有效位数(如果有这样的文字)不会存储在任何地方。

简单地说,没有办法获得

0.0000822120183514065

甚至

8.22120183514065e-05

的数字

0.0000822120183514065132508730204818903075647540390491485595703125

从可用信息中获取。

如果你以字符串

开头会有所不同
8.22120183514065e-05

或者如果您知道所需的精度,则可以使用

创建上述字符串
sprintf('%.*e', $significant_digits-1, $n)

如果你有这个,你可以根据需要执行字符串操作来移动.

$n =~ s/^\d\K\.// ? $n =~ s/^\d+\Ke([+-]\d+)\z// : $n =~ s/^\d\Ke([+-]\d+)\z// or die;
my $exp = $1 + 1;
if    ( $exp <= 0         ) { $n = '0.' . ( '0' x -$exp ) . $n;  }
elsif ( $exp < length($n) ) { substr($n, $exp, 0, '.');          }
elsif ( $exp > length($n) ) { $n .= '0' x ( $exp - length($n) ); }
$ perl -e'printf "%.70f\n", 8.22120183514065e-05;'
0.0000822120183514065132508730204818903075647540390491485595703125000000

$ perl -e'printf "%.70e\n", 8.22120183514065e-05;'
8.2212018351406513250873020481890307564754039049148559570312500000000000e-05

$ perl -e'printf "%.*e\n", 14, 8.22120183514065e-05;'
8.22120183514065e-05