186

10進数(浮動小数点)を最も近い整数に丸めるにはどうすればよいですか?

例えば

1.2 = 1
1.7 = 2
4

14 に答える 14

206

の出力perldoc -q round

Perlにはround()関数がありますか?ceil()とfloor()はどうですか?関数をトリガーしますか?

int()に向かって切り捨てられる ことを忘れないでください0。特定の桁数に丸める場合、sprintf()またはprintf()通常は最も簡単なルートです。

    printf("%.3f", 3.1415926535);       # prints 3.142

このPOSIXモジュール(標準のPerlディストリビューションの一部)は、、、 およびその他の多くの数学関数と三角関数を実装します ceil()floor()

    use POSIX;
    $ceil   = ceil(3.5);                        # 4
    $floor  = floor(3.5);                       # 3

5.000〜5.003 perlsでは、Math::Complex モジュールで三角法が実行されました。5.004では、Math::Trigモジュール(標準のPerlディストリビューションの一部)が三角関数を実装しています。内部的にはMath::Complexモジュールを使用し、一部の関数は実軸から複素平面に分割できます。たとえば、2の逆正弦です。

金融アプリケーションでの丸めは深刻な影響を与える可能性があるため、使用する丸め方法を正確に指定する必要があります。このような場合、Perlで使用されているシステムの丸めを信頼するのではなく、必要な丸め関数を自分で実装することをお勧めします。

理由を確認するには、中間地点の交代でまだ問題が発生することに注意してください。

    for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i}

    0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
    0.8 0.8 0.9 0.9 1.0 1.0

Perlのせいにしないでください。これはCの場合と同じです。IEEEはこれを行う必要があると言っています。絶対値が2**31(32ビットマシンの)整数であるPerl番号は、数学的な整数とほとんど同じように機能します。その他の番号は保証されません。

于 2008-10-07T13:54:12.120 に答える
148

中間マークなどに関する複雑な回答に異議を唱えるわけではありませんが、より一般的な(そしておそらく些細な)ユースケースについては、次のとおりです。

my $rounded = int($float + 0.5);

アップデート

負になる可能性がある場合$floatは、次のバリエーションで正しい結果が得られます。

my $rounded = int($float + $float/abs($float*2 || 1));

この計算では、-1.4 は -1 に丸められ、-1.6 は -2 に丸められ、ゼロは爆発しません。

于 2009-08-13T21:26:05.420 に答える
78

Math :: Round:のようなモジュールを使用できます。

use Math::Round;
my $rounded = round( $float );

または、大雑把な方法でそれを行うことができます:

my $rounded = sprintf "%.0f", $float;
于 2008-10-07T13:54:09.920 に答える
47

printf または sprintf を使用する場合は、 Round half to evenメソッドを使用することに注意してください。

foreach my $i ( 0.5, 1.5, 2.5, 3.5 ) {
    printf "$i -> %.0f\n", $i;
}
__END__
0.5 -> 0
1.5 -> 2
2.5 -> 2
3.5 -> 4
于 2008-10-07T15:37:02.927 に答える
9

perldoc/perlfaqを参照してください:

int()単に 0 に向かって切り捨てられることを覚えておいてください。特定の桁数に丸める場合、sprintf()またはprintf()通常は最も簡単な方法です。

 printf("%.3f",3.1415926535);
 # prints 3.142

POSIXモジュール (標準 Perl ディストリビューションの一部) は、ceil()floor()、およびその他の多数の数学関数と三角関数を実装しています。

use POSIX;
$ceil  = ceil(3.5); # 4
$floor = floor(3.5); # 3

5.000 から 5.003 perl では、Math::Complexモジュール内で三角法が行われていました。

5.004 では、Math::Trigモジュール (標準 Perl ディストリビューションの一部) > は三角関数を実装します。

内部的にMath::Complexモジュールを使用し、一部の関数は実軸から複素平面に分割できます。たとえば、2 の逆正弦です。

金融アプリケーションでの丸めは深刻な影響を与える可能性があるため、使用する丸め方法を正確に指定する必要があります。このような場合、Perl が使用しているシステムの丸めを信頼するのではなく、必要な丸め関数を自分で実装するのがおそらく得策です。

理由を確認するには、中間点の交替で問題が発生することに注意してください。

for ($i = 0; $i < 1.01; $i += 0.05)
{
   printf "%.1f ",$i
}

0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1.0 1.0

Perlのせいにしないでください。C と同じです。IEEE は、これを行う必要があると言っています。絶対値が 2**31 未満の整数 (32 ビット マシン上) である Perl の数値は、数学的な整数とほとんど同じように機能します。他の数値は保証されません。

于 2008-10-07T13:58:29.757 に答える
3

外部モジュールは必要ありません。

$x[0] = 1.2;
$x[1] = 1.7;

foreach (@x){
  print $_.' = '.( ( ($_-int($_))<0.5) ? int($_) : int($_)+1 );
  print "\n";
}

私はあなたの主張を見逃しているかもしれませんが、これは同じ仕事をするためのはるかにクリーンな方法だと思いました。

これは、要素内のすべての正の数を調べ、その数と丸められた整数を前述の形式で出力することです。コードは、小数のみに基づいて、それぞれの丸められた正の整数を連結します。int($ _)は基本的に数値を切り捨てるので、($ -int($))は小数点以下をキャプチャします。小数点以下が(定義上)厳密に0.5未満の場合は、数値を切り捨てます。そうでない場合は、1を追加して切り上げます。

于 2011-06-13T20:51:58.523 に答える
2

以下は、正または負の数値を指定された小数点以下の桁数に丸めます。

sub round ()
{
    my ($x, $pow10) = @_;
    my $a = 10 ** $pow10;

    return (int($x / $a + (($x < 0) ? -0.5 : 0.5)) * $a);
}
于 2014-09-12T14:13:38.203 に答える
1

負の数は、注意が必要な癖を追加する可能性があります。

printf- スタイルのアプローチでは正しい数値が得られますが、表示がおかしくなる可能性があります。-私たちは、このメソッドが (私の意見では、ばかげて)すべきかどうかのサインを入れることを発見しました。たとえば、小数点以下 1 桁に丸められた -0.01 は、0 ではなく、-0.0 を返します。printfスタイル アプローチを実行する予定で、小数点が不要であることがわかっている場合は、%dand notを使用し%fます (小数点以下が必要な場合は、表示がおかしくなる)。

それは正しく、数学では大したことではありませんが、表示では「-0.0」のようなものを表示するだけで奇妙に見えます。

int メソッドの場合、負の数は結果として必要なものを変更できます (ただし、それらを正しくすることができるいくつかの引数があります)。

あなたint + 0.5がそれをそのように機能させたくない限り、負の数で実際の問題を引き起こしますが、ほとんどの人はそうではないと思います。-0.9 はおそらく 0 ではなく -1 に丸める必要があります。マイナスを床ではなく天井にしたいことがわかっている場合は、ワンライナーでそれを行うことができます。それ以外の場合は、マイナーで int メソッドを使用することをお勧めします。変更 (これは明らかに整数を返す場合にのみ機能します:

my $var = -9.1;
my $tmpRounded = int( abs($var) + 0.5));
my $finalRounded = $var >= 0 ? 0 + $tmpRounded : 0 - $tmpRounded;
于 2011-08-22T22:38:37.807 に答える
1

以下は、値を合計する 5 つの異なる方法のサンプルです。1 つ目は、合計を実行する単純な方法です (そして失敗します)。2 番目は を使用しようとしますsprintf()が、これも失敗します。sprintf()最後の 2 つ (4 番目と 5 番目)がfloor($value + 0.5).

 use strict;
 use warnings;
 use POSIX;

 my @values = (26.67,62.51,62.51,62.51,68.82,79.39,79.39);
 my $total1 = 0.00;
 my $total2 = 0;
 my $total3 = 0;
 my $total4 = 0.00;
 my $total5 = 0;
 my $value1;
 my $value2;
 my $value3;
 my $value4;
 my $value5;

 foreach $value1 (@values)
 {
      $value2 = $value1;
      $value3 = $value1;
      $value4 = $value1;
      $value5 = $value1;

      $total1 += $value1;

      $total2 += sprintf('%d', $value2 * 100);

      $value3 = sprintf('%1.2f', $value3);
      $value3 =~ s/\.//;
      $total3 += $value3;

      $total4 += $value4;

      $total5 += floor(($value5 * 100.0) + 0.5);
 }

 $total1 *= 100;
 $total4 = floor(($total4 * 100.0) + 0.5);

 print '$total1: '.sprintf('%011d', $total1)."\n";
 print '$total2: '.sprintf('%011d', $total2)."\n";
 print '$total3: '.sprintf('%011d', $total3)."\n";
 print '$total4: '.sprintf('%011d', $total4)."\n";
 print '$total5: '.sprintf('%011d', $total5)."\n";

 exit(0);

 #$total1: 00000044179
 #$total2: 00000044179
 #$total3: 00000044180
 #$total4: 00000044180
 #$total5: 00000044180

への依存を削除するには、 をfloor($value + 0.5)に置き換えることができることに注意してください。int($value + 0.5)POSIX

于 2010-12-21T21:06:50.170 に答える
0

sprintf の私のソリューション

if ($value =~ m/\d\..*5$/){
    $format =~ /.*(\d)f$/;
    if (defined $1){
       my $coef = "0." . "0" x $1 . "05";    
            $value = $value + $coef;    
    }
}

$value = sprintf( "$format", $value );
于 2011-11-09T11:35:35.910 に答える
0

浮動小数点数全体 (つまり、12347.9999 または 54321.0001) から整数値を取得することのみに関心がある場合は、このアプローチ (上記から借用して変更したもの) でうまくいきます。

my $rounded = floor($float + 0.1); 
于 2016-09-23T19:47:44.850 に答える
-2
cat table |
  perl -ne '/\d+\s+(\d+)\s+(\S+)/ && print "".**int**(log($1)/log(2))."\t$2\n";' 
于 2009-08-13T14:25:56.847 に答える