문제

소수점 번호 (부동 소수점)를 가장 가까운 정수로 어떻게 반올림 할 수 있습니까?

예를 들어

1.2 = 1
1.7 = 2
도움이 되었습니까?

해결책

출력 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와 동일합니다. IEEE는이 작업을 수행해야한다고 말합니다. 절대 값이 정수 인 Perl 번호 2**31 (32 비트 기계에서)는 수학적 정수와 거의 비슷합니다. 다른 숫자는 보장되지 않습니다.

다른 팁

더 일반적인 (그리고 아마도 사소한) 사용을 위해 반쯤 마크 등의 복잡한 답변에 동의하지 않는 반면 :

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

업데이트

당신의 것이 가능하다면 $float 부정적으로, 다음 변형은 올바른 결과를 낳습니다.

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

이 계산을 사용하면 -1.4는 -1로 반올림하고 -1.6 ~ -2로 반올림되며 0은 폭발하지 않습니다.

같은 모듈을 사용할 수 있습니다 수학 :: 라운드:

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

또는 조잡한 방법으로 할 수 있습니다.

my $rounded = sprintf "%.0f", $float;

printf 또는 sprintf를 사용하기로 결정한 경우 반쪽에서 짝수 방법.

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

보다 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의 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와 동일합니다. IEEE는이 작업을 수행해야한다고 말합니다. 절대 값이 2 ** 31 (32 비트 머신에서) 미만의 정수 인 Perl 번호는 수학 정수와 거의 비슷합니다. 다른 숫자는 보장되지 않습니다.

외부 모듈이 필요하지 않습니다.

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

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

나는 당신의 요점을 놓치고 있을지 모르지만, 이것이 같은 일을하는 훨씬 깨끗한 방법이라고 생각했습니다.

이것이하는 일은 요소의 모든 양수를 걸어 가고, 언급 한 형식으로 숫자와 둥근 정수를 인쇄하는 것입니다. 이 코드는 각각의 둥근 정수를 긍정적 인 정수로 만듭니다. int ($ _) 기본적으로 라운드 다운 숫자 so ($-int ($)) 소수를 포착합니다. 소수점이 (정의에 따라) 엄격하게 0.5 미만인 경우 숫자를 반올림하십시오. 그렇지 않은 경우 1을 추가하여 라운드 업.

다음은 양수 또는 음수 숫자를 주어진 소수점 위치로 반올림합니다.

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

    return (int($x / $a + (($x < 0) ? -0.5 : 0.5)) * $a);
}

다음은 값을 요약하는 5 가지 방법의 샘플입니다. 첫 번째는 요약을 수행하는 순진한 방법입니다. 두 번째로 사용하려는 시도 sprintf(), 그러나 그것은 너무 실패합니다. 세 번째 용도 sprintf() 마지막 두 (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.

마이너스 숫자는 사람들이 알아야 할 몇 가지 단점을 추가 할 수 있습니다.

printf-스타일 접근 방식은 우리에게 올바른 숫자를 제공하지만 일부 홀수 디스플레이를 초래할 수 있습니다. 우리는이 방법 (내 의견으로는 어리석게도)이 - 해야할지 여부에 따라 서명하십시오. 예를 들어, 10.01은 10 자리 자리로 반올림되어 0이 아닌 -0.0을 반환합니다. printf 스타일 접근법, 당신은 소수점을 원하지 않는다는 것을 알고 있습니다. %d 그리고 아닙니다 %f (소마가 필요할 때, 디스플레이가 원해가 될 때입니다).

그것이 맞고 수학의 경우 큰 문제는 없지만, 디스플레이를 위해서는 "-0.0"과 같은 것을 보여주는 이상하게 보입니다.

int 메소드의 경우, 마이너스 숫자는 결과적으로 원하는 것을 변경할 수 있습니다 (그러나 올바른 주장이 있지만).

그만큼 int + 0.5 당신이 그런 식으로 일하기를 원하지 않는 한, 음성 숫자로 실제 문제를 일으키지 만 대부분의 사람들은 그렇지 않다고 생각합니다. -0.9는 아마도 0이 아닌 -1로 반올림해야합니다. 수정 (이것은 분명히 정수를 되 찾는 데만 작동합니다.

my $var = -9.1;
my $tmpRounded = int( abs($var) + 0.5));
my $finalRounded = $var >= 0 ? 0 + $tmpRounded : 0 - $tmpRounded;

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 );

전체 부동 소수점 번호 (예 : 12347.9999 또는 54321.0001)에서 정수 값을 얻는 데만 관심이있는 경우이 접근법 (위에서 빌려서 수정)은 다음과 같습니다.

my $rounded = floor($float + 0.1); 
cat table |
  perl -ne '/\d+\s+(\d+)\s+(\S+)/ && print "".**int**(log($1)/log(2))."\t$2\n";' 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top