2

浮動小数点数を切り上げたい。たとえば、sprintf '%.4f', 0.12345return0.1235sprintf '%.4f', 0.12325return 0.1232. 2 番目の例では0.1233、 ではなくを出力し0.1232ます。

sprintfPerl では十分ではありません。Math::BigFloatできますが、少しやり過ぎです。

切り上げる他の効果的な方法があるかどうか、または Perl に他のモジュールがあるかどうかは誰にもわかりませんか?

4

3 に答える 3

1

sprintf数値を丸める正確な方法は、システム ライブラリが数値を丸める方法によって異なります。数値の丸め方法を正確に制御する必要がある場合は、目的の丸めを明示的に実装するライブラリを使用するか、必要に応じて丸める関数を作成する必要があります。

たとえば、正の数を任意の精度に丸めるには、5 を切り上げます。

sub round {
    my $numer     = shift;
    my $precision = shift;
    return int($numer * 10 ** $precision + 0.5) * 10 ** -$precision;
}

ただし、これは負の数に対して正しく丸められません。-0.12324 は誤って -0.1231 に丸められます。5 が切り上げられる (つまり、正の無限大に向かう) 解決策は、floorの代わりに使用することですint

use POSIX qw(floor);
sub round {
    my $numer     = shift;
    my $precision = shift;
    return floor($numer * 10 ** $precision + 0.5) * 10 ** -$precision;
}

代わりに、5 を最大の絶対値に丸める (つまり、0 から遠ざけるように丸める) 必要がある場合は、負の数の単純なチェックを追加して、それらを正しい方向に丸めることができます。

sub round {
    my $numer     = shift;
    my $precision = shift;
    my $direction = $numer >= 0 ? 0.5 : -0.5;
    return int($numer * 10 ** $precision + $direction) * 10 ** -$precision;
}

すべての数値に対して 5 を一方向に丸めることによる偏りが許容されず、浮動小数点数の (10 進数の) 丸めがバイナリ形式の不正確さによるエラーの可能性がある状況で使用される丸めには、より複雑な規則があります。

于 2012-07-18T14:32:25.270 に答える
0

これは私にとってはうまくいきました:

print sprintf '%.*f', 4, 0.12325

あなたのコードは私にとってもうまくいきます。そのコードを単独でテストしましたか?
perl のバージョンも教えていただけますか ( perl -v)?

于 2012-07-18T10:11:38.000 に答える
0

Perlsprintfは、与えられたデータと同程度にしかできません。0.12345 または 0.12325 に正確に等しい浮動小数点数はありません。

  • 0.12345 に最も近い浮動小数点数は正確に2223877495995551/2**54≈ 0.1234 5 0000000000004 であり、入力値よりわずかに大きい値です。
  • 0.12325 に最も近い浮動小数点数は正確に4440549232587309/2**55≈ 0.1232 4 9999999999998 であり、入力値よりわずかに小さい値です。

後者の 10 進数の 5 桁目は 5 ではなく 4 であることに注意してください。通常の規則で小数点以下 4 桁に丸めると、それぞれ0.1235と 0.1232 になります。

使用は少しやり過ぎだとおっしゃってMath::BigFloatいますが、本当に必要なのは 10 進演算なので、やり過ぎは避けられません。

于 2021-11-21T23:07:57.680 に答える