从科学计数法转换为十进制计数法时如何保持显示精度?
How can I retain display precision when converting from scientific to decimal notation?
考虑以下浮点数:
8.22120183514065e-05
现在显然 (s)printf
是这里的标准做法,但是 %f
改变了它的精度:
printf "%f", 8.22120183514065e-05; # 0.000082
使用任意大的精度,比如 %.30f
,添加额外的数字 (...6505
):
printf "%.30f", 8.22120183514065e-05; # 0.000082212081351406505000000000
有没有办法在事先不知道其准确精度的情况下保持科学记数法中存在的精度?
我相信您是在问如何对数字进行字符串化,以使字符串化与生成该数字的代码文字具有相同数量的有效数字。
那是不可能的。生成数字的代码文字中有效数字的数量(如果有这样的文字)不存储在任何地方。
简单的说,没有办法得到
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;
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
考虑以下浮点数:
8.22120183514065e-05
现在显然 (s)printf
是这里的标准做法,但是 %f
改变了它的精度:
printf "%f", 8.22120183514065e-05; # 0.000082
使用任意大的精度,比如 %.30f
,添加额外的数字 (...6505
):
printf "%.30f", 8.22120183514065e-05; # 0.000082212081351406505000000000
有没有办法在事先不知道其准确精度的情况下保持科学记数法中存在的精度?
我相信您是在问如何对数字进行字符串化,以使字符串化与生成该数字的代码文字具有相同数量的有效数字。
那是不可能的。生成数字的代码文字中有效数字的数量(如果有这样的文字)不存储在任何地方。
简单的说,没有办法得到
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;
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