문제

내 과정에서 나는 다음과 같이 들었다.

연속 값은 대략 메모리로 표시되므로 플로트로 컴퓨팅에는 반올림 오류가 포함됩니다. 이것들은 비트 패턴의 작은 불일치입니다. 따라서 테스트 e==f IF가 안전하지 않습니다 e 그리고 f 플로트입니다.

Java를 언급합니다.

이것이 사실입니까? 비교 진술을 사용했습니다 double모래 floatS와 반올림 문제가 없었습니다. 교과서에서 비슷한 것을 읽은 적이 없습니다. 확실히 가상 기계가 이것을 설명합니까?

도움이 되었습니까?

해결책

그건 진실이야.

플로팅 포인트 값이 유한 수의 비트로 메모리에서 어떻게 표시되는지에 대한 고유 한 제한입니다.

예를 들어이 프로그램은 "false"를 인쇄합니다.

public class Main {
  public static void main(String[] args) {
    double a = 0.7;
    double b = 0.9;
    double x = a + 0.1;
    double y = b - 0.1;
    System.out.println(x == y);
  }
}

'=='과의 정확한 비교 대신 일반적으로 어느 정도의 정밀도를 결정하고 숫자가 "충분히 가까운 지"묻습니다.

System.out.println(Math.abs(x - y) < 0.0001);

다른 팁

이것은 부동 소수점을 사용하는 다른 언어만큼 Java에 적용됩니다. 하드웨어에서 부동 소수점 값을 표현하는 데 내재되어 있습니다.

부동 소수점 값에 대한 자세한 정보 :

모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 것

예, Base-2에서 정확히 0.1을 나타내는 것은 Base 10에서 정확히 1/3을 표현하려는 것과 동일합니다.

이것은 항상 사실입니다. 플로트 포인트 표현을 사용하여 정확하게 표현할 수없는 숫자가 있습니다. 예를 들어 PI를 고려하십시오. 유한 한 스토리지 내에서 무한 자릿수를 가진 숫자를 어떻게 표현 하시겠습니까? 따라서 숫자를 비교할 때 숫자의 차이가 일부 엡실론보다 작은 지 확인해야합니다. 또한 BigDecimal 및 BigInteger와 같이 더 큰 정확도를 달성하는 데 도움이되는 몇 가지 클래스가 있습니다.

맞습니다. Java는 그것과 관련이 없으며, 문제는 부동 소수점 수학에 내재되어 있습니다. 어느 언어.

교실 수준의 문제로 종종 문제를 해결할 수 있지만 실제 세계에서는 효과가 없습니다. 때로는 교실에서 작동하지 않습니다.

오래 전부터 학교에서 돌아온 사건. 소개 수업의 교사는 최종 시험 문제를 배정하여 많은 학생들에게 진정한 멍청이를 증명했습니다. 효과가 없었으며 그 이유를 알지 못했습니다. (나는 이것을 실험실 조교로 보았고, 수업에 참여하지 않았다.) 마침내 일부는 나에게 도움을 요청하기 시작했고 일부 조사는 문제를 밝혔다.

이제이 문제에 대한 두 가지 기본 접근법이있었습니다. 무차별 인력 1 (우연히이 경우 매번 동일한 오류가 발생함에 따라 우연히 작동)과 더 우아한 (다른 오류를 만들고 작동하지 않을 것입니다). 우아한 접근 방식은 그 이유를 모르고 벽돌 벽에 부딪 칠 것입니다. 나는 그들을 도와 주었고 왜 질문이 있으면 왜 나에게 연락하는 의견에 갇혔다.

물론 다음 학기에 나는 이것에 대해 그에게서 들었고 기본적으로 간단한 작은 프로그램으로 전체 부서에 바닥을 두었습니다.

10 X = 3000000
20 X = X + 1
30 If X < X + 1 goto 20
40 Print "X = X + 1"

부서의 모든 교사가 생각했던 것에도 불구하고 할 것이다 끝내다. 3 백만 종자는 단순히 더 빨리 끝나는 것입니다. (기본을 모른다면 : 여기에는 특수 효과가 없으며 부동 소수점 번호의 정밀도를 소진합니다.)

그렇습니다. 다른 대답이 말했듯이. 플로팅 포인트 정확도에 대한이 기사를 추천한다고 덧붙이고 싶습니다. 부유물을 시각화합니다

대부분의 CPU (및 컴퓨터 언어)는 IEEE 754 Floating Point 산술을 사용합니다. 이 표기법을 사용 하여이 표기법에는 정확한 표현이없는 소수점 숫자가 있습니다 (예 : 0.1). 따라서 1을 10으로 나누면 정확한 결과를 얻지 못합니다. 몇 가지 계산을 연속으로 수행 할 때 오류가 요약됩니다. 파이썬에서 다음 예제를 시도하십시오.

>>> 0.1
0.10000000000000001
>>> 0.1 / 7 * 10 * 7 == 1
False

그것은 실제로 수학적으로 기대할 수있는 것이 아닙니다.

그건 그렇고 : 부동 소수점 번호에 관한 일반적인 오해는 결과가 정확하지 않으며 안전하게 통합 될 수 없다는 것입니다. 실제로 숫자의 일부를 사용하는 경우에만 해당됩니다. 모든 수학이 정수 도메인에있는 경우 복식과 부유물은 INT와 정확히 동일하며 안전하게 비교할 수 있습니다. 예를 들어 루프 카운터로 안전하게 사용할 수 있습니다.

예, Java도 사용합니다 부동 소수점 산수.

물론 그것은 사실입니다. 그것에 대해 생각하십시오. 모든 숫자는 이진으로 표시되어야합니다.

사진 : "1000"은 0.5 또는 1/2, 즉 2 ** -1입니다. 그런 다음 "0100"은 0.25 또는 1/4입니다. 내가 어디로 가는지 알 수 있습니다.

이런 식으로 몇 개의 숫자를 대표 할 수 있습니까? 2 ** 4. 더 많은 비트를 추가하면 사용 가능한 공간이 복제되지만 결코 무한하지 않습니다. 1/3 또는 1/10, 물질 1/n의 경우 2 중 2가 아닌 숫자를 실제로 표현할 수 없습니다.

1/3은 "0101"(0.3125) 또는 "0110"(0.375) 일 수 있습니다. 값을 곱하면 3을 곱하면 1이 아닙니다. 물론 특별 규칙을 추가 할 수 있습니다. "3 번 '0101'을 추가하면 1을 만들 때"...이 접근법은 장기적으로 작동하지 않습니다. 당신은 몇 가지를 잡을 수 있지만 1/6 회 2는 어떻습니까?

그것은 이진 표현의 문제가 아니며, 유한 표현에는 당신이 표현할 수없는 숫자가 있으며 결국 무한합니다.

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