2017-01-11 10 views
2

は、以下のフロートを考慮してください。科学的表記から10進表記への変換時に表示の精度を保持するにはどうすればよいですか?

8.22120183514065e-05 

今、明らかに(s)printfはここで行うための標準的なことですが、%fは、その精度を変える:

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

任意の大きさの精度を使用して、%.30fを言って、追加の数字を追加します(...6505):

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

正確な精度を事前に知らなくても、科学記法に存在する精度を維持する方法はありますか?

+0

あの、ありませんか? '8.22120183514065e-05'という文字列自体は、例えばIEEE754規格に示されている「真の」値の有限精度表現である。 – mob

+0

文字列値の文字列操作について質問している場合を除き、その場合は異論を取り消します。 – mob

+0

指数部の数値を精度に加えたいと思っています。もしそれが 'e-05'なら、あなたが通常持っているもの(デフォルトでは15)に5桁を追加します。それが 'e03'なら3つ追加します。私は最初に手作業で作業しなくても、指数を取得する方法は見当たりません。 – zdim

答えて

3

私は、文字列に数字を生成したコードリテラルと同じ数字があるように、文字列をどのように文字列化するかを尋ねていると思います。

これは不可能です。数値を生成したコードリテラルの有効桁数(そのようなリテラルがあったとしても)はどこにも格納されません。簡単に言えば

、入手可能な情報から数

0.0000822120183514065132508730204818903075647540390491485595703125 

から

0.0000822120183514065 

あるいは

8.22120183514065e-05 

を取得する方法はありません。


あなたは、文字列

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 
+0

十分に公正。私はこれを行うための何らかの組み込みの 'sprintf'-yの方法を望んでいました。しかたがない。 – Zaid

+1

番号からですか?情報はそこにはありません。文字列からですか?精度の低下を引き起こす可能性があります。文字列形式で作業するのが最適です。解決策が答えに追加されました。 – ikegami

関連する問題