Perl의 통계에서 무한 루프를 유발하는 반올림 오류를 어떻게 해결할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/944553

문제

나는 사용하고있다 통계 :: 설명 Perl의 라이브러리는 주파수 분포를 계산하고 부동 소수점 반올림 오류 문제에 대해 발생합니다.

0.205와 0.205 (다른 숫자에서 가져 와서 그에게 스프린트를 가져옵니다)라는 두 가지 값으로 통계 모듈로 전달하고 주파수 분포를 계산하도록 요청하지만 무한 루프에 갇혀 있습니다.

디버거를 밟고있는 것을 볼 수 있습니다.

my $interval = $self->{sample_range}/$partitions;

my $iter = $self->{min};

while (($iter += $interval) <  $self->{max}) {

  $bins{$iter} = 0;

  push @k, $iter;  ##Keep the "keys" unstringified

}

$ self> sample_range (범위는 max-min)가 내가 예상하는대로 0이 아닌 2.77555756156289E-17을 반환합니다. 이것은 루프 ((min+= 범위) <max))가 (모든 의도 및 목적을 위해) 무한 루프로 들어갑니다.

db <8> print $ self-> {max};
0.205
db <9> print $ self-> {min};
0.205
db <10> print $ self-> {max}-$ self-> {min};
2.77555756156289E-17

따라서 이것은 반올림 문제처럼 보입니다. 그래도 이것을 내 편에 고치는 방법을 생각할 수 없으며 라이브러리 편집이 좋은 생각인지 확실하지 않습니다. 해결 방법이나 대안의 제안을 찾고 있습니다.

건배, 닐

도움이 되었습니까?

해결책

나는 통계 :: 서술 관리자입니다. 숫자 특성으로 인해 많은 반올림 문제 가보고되었습니다. 나는이 특별한 것이 += 대신 분열에 곱셈을 사용하여 최근에 발표 한 것들에 이후 버전으로 고정되었다고 생각합니다.

이용 해주세요 최신 버전 CPAN에서 더 나아질 것입니다.

다른 팁

정확히 반올림 문제가 아닙니다. 당신은 더 정확한 값을 볼 수 있습니다.

printf("%.18g %.18g", $self->{max}, $self->{min});

모듈에 샘플 범위를 $ 파티션 조각으로 나눌 수 있다고 가정하는 모듈에 결함이있는 것처럼 보입니다. 부동 소수점에는 무한한 정밀도가 없기 때문에 항상 가능하지는 않습니다. 귀하의 경우, 최소 및 최대 값은 정확히 인접한 대표 값이므로 둘 이상의 파티션이있을 수 없습니다. 모듈이 파티션을 정확히 사용하는 것이 정확히 무엇인지 알지 못 하므로이 영향이 무엇인지 잘 모르겠습니다. 모듈의 또 다른 가능한 문제는 숫자를 해시 키로 사용한다는 것입니다.이 숫자는 값을 약간 반올림하는 암시 적으로 줄이됩니다.

모듈에 공급하기 전에 문자열 화를 통해 데이터를 세탁하는 데 약간의 성공을 거둘 수 있습니다.

$data = 0+"$data";

이렇게하면 적어도 (기본 인쇄 정밀도)가 동일하게 보이는 두 개의 숫자가 실제로 동일하게 보장됩니다.

무한 루프가 발생하지 않아야합니다. 그 루프가 무한하게 만드는 것은 $self->{sample_range}/$partitions 0입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top