2014-03-12 2 views
0

다음 코드를 사용하여 dt * j가 정수 인 경우 결과를 저장하기 위해 Matlab을 사용하려고했습니다. .matlab mod() 함수가 잘못된 답을 제공합니다.

j=1; 
dt = 1E-05; 
a=[]; 
while dt*j <=20 
    if mod(dt*j,1) ==0 
     a=[a;[dt*j,j]]; 
    end 
j=j+1; 
end 

그러나 Matlab은 잘못된 결과를 제공합니다. 아래에 표시된 것처럼 일부 정수 (3,6,7,11 등 ...)가 누락되었습니다.

a = 
1  100000 
2  200000 
4  400000 
5  500000 
8  800000 
9  900000 
10  1000000 
16  1600000 
17  1700000 
18  1800000 
19  1900000 
20  2000000 

dt = 1E-4를 사용하여 다시 시도했으며 올바른 결과를 제공합니다. 아무도 여기서 무슨 일이 일어나는지 말해 줄 수 없습니까? 고맙습니다.

+3

부동 소수점 정밀도 오류의 또 다른 예입니다. 틀린 것은 아니다.'dt * j'는 정확하게 기대 값이 아니다. – Daniel

+0

예, dt * 300000 == 3 ans = 0, dt * 400000 == 4, ans = 1 일부 숫자 만 빠져 있기 때문에 혼란 스러웠습니다. 그러나 컴퓨터 상점 번호와 관련이 있다고 생각합니다. – user3413078

+0

부동 소수점 질문입니다. 산수. 몇 가지 문제점이 있습니다. http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Daniel

답변

2

직접 ==와 부동 소수점 숫자를 비교,하지만 그들은 정말 가까운 대신 확인하지 마십시오 내가 추측하고

j=1; 
dt = 1E-05; 
a=[]; 
while dt*j <=20 
    if abs(mod(dt*j,1)) < 1e-10 
     a=round([a;[dt*j,j]]); 
    end 
j=j+1; 
end 
+0

감사합니다! 그것은 작동합니다. 나는이 == 비교를하기 전에 사용했으나이 문제는 오늘날까지는 결코 나타나지 않는다 ... – user3413078

0

는 이상한 반올림 오류가있다. 나는 당신의 코드를 시도했고 나는 같은 결과를 얻고있다. 하나의 접근법은 mod (dt * j, 1) == 0을 사용하는 것이 아니라 mod (dt * j, 1) < dt 또는 mod (dt * j, 1) < thresh를 사용하여 임계 값을 설정할 수 있습니다. 트릭을 수행 할 정도로 제로에 가깝습니다.

배율 부동 소수점 형식 페이지의 위키 피 디아 페이지에서 다음과 같이 말합니다. 1.0000000000000002, 가장 작은 수> 1. 두 배를 사용하여 추정하면 약 2E-16의 수치 해상도를 얻을 수 있습니다. 따라서 2E-15의 임계 값을 사용하여 안전 할 수 있습니다.

+0

숫자 분해능은'eps'에 의해 주어진다. 실제로 그것은 약 2e-16이다. –

관련 문제