문제

나는 최근에 Haskell 튜토리얼을 겪고 있었고 대화식에서 간단한 Haskell 표현을 시도 할 때이 행동을 발견했습니다. ghci 껍데기:

Prelude> 1.1 + 1.1 == 2.2
True
Prelude> 1.1 + 1.1 + 1.1 == 3.3
False
Prelude> 1.1 + 1.1 + 1.1 > 3.3
True
Prelude> 1.1 + 1.1 + 1.1
3.3000000000000003

그 이유를 아는 사람이 있습니까?

도움이 되었습니까?

해결책

왜냐하면 1.1 그리고 3.3 ~이다 부동 소수점 번호. .1 또는 .3과 같은 10 진수 분획은 이진 부동물 지점 수에서 정확하게 표현할 수 없습니다. .1은 1/10을 의미합니다. 이진에서이를 나타내려면, 각 분수 숫자는 1/2를 나타냅니다.N (1/2, 1/4, 1/8 등), 무한히 반복되는 무한 수의 숫자가 필요합니다.

이것은베이스 10에서 1/3을 나타내는 것과 정확히 같은 문제입니다.베이스 10에서는 1/3을 정확하게 나타내려면 영원히 .33333 ... 영원히 무한 수의 숫자가 필요합니다. 따라서베이스 10에서 일하는 것은 보통 .33과 같은 것입니다. 그러나 그 사본 3 부를 추가하면 1이 아닌 .99를 얻습니다.

주제에 대한 자세한 내용은 읽으십시오 모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 것.

Haskell에서 합리적 숫자를보다 정확하게 표현하려면 항상 합리적인 데이터 유형을 사용할 수 있습니다. Ratio; Bignums와 결합 (임의로 큰 정수, Integer Haskell에서는 반대로 Int 분자 및 분모의 유형으로 고정 된 크기입니다)는 임의로 정확한 합리적 숫자를 나타낼 수 있지만 하드웨어로 구현되고 속도에 최적화 된 부동 소수점 수보다 속도가 상당히 느려집니다.

플로팅 포인트 숫자는 과학적 및 수치 계산을 위해 최적화로 고속으로 정밀도를 트레이드하여 반올림을 알고있는 한 소량의 컴퓨터를 수행 할 수 있으며 계산에 미치는 영향 .

다른 팁

부동 소수점 숫자는 정확하지 않기 때문입니다(위키 백과)

합리적인 유형을 사용하여 Haskell의 부동 소수점 오류를 피할 수 있습니다.

Prelude Data.Ratio> let a = (11 % 10) + (11 % 10) + (11 % 10)
Prelude Data.Ratio> a > (33 % 10)
False
Prelude Data.Ratio> fromRational a
3.3

물론, 당신은 정확도 증가에 대한 성능 페널티를 지불합니다.

일반적인 부동 소수점 오류 문제처럼 보입니다.

보다 부동 소수점/반올림 오류의 간단한 예는 무엇입니까?

IEEE 부동 소수점 번호가 작동하는 방식과 관련이 있습니다.

1.1은 플로팅 포인트에서 1.1000000000000001로 표시되며 3.3은 3.2999999999999998로 표시됩니다.

따라서 1.1 + 1.1 + 1.1은 실제로입니다

1.1000000000000001 + 1.1000000000000001 + 1.1000000000000001 = 3.3000000000000003

보시다시피 실제로는 실제로 3.2999999999999998보다 큽니다.

일반적인 해결 방법은 평등을 평가하지 않거나 숫자가 대상 내에 있는지 확인하는 것입니다.

예 : 둘 다 참이면 합계는 3.3 (허용 오류 내)과 "동일"합니다.

1.1 + 1.1 + 1.1 < 3.3 + 1e9 
1.1 + 1.1 + 1.1 > 3.3 - 1e9

IEEE 754 표현을 사용하여 정확히 수레를 표현할 수있는 수레는 거의 없으므로 항상 약간 떨어질 것입니다.

일반적으로 평등을 위해 부유물을 비교해서는 안됩니다 (위에 설명 된 이유로). 내가 생각할 수있는 유일한 이유는 당신이 "이 가치가 바뀌 었습니까?"라고 말하고 싶은 경우입니다. 예를 들어, "if (NewsCore /= OldScore)"그런 다음 조치를 취하십시오. 두 개의 별도 계산 결과를 비교하여 동일인지 확인하기 위해 두 개의 별도 계산 결과를 비교하지 않는 한 괜찮습니다 (수학적으로도 수학적으로도 다른 둥글 수도 있기 때문입니다).

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