2013-08-12 19 views
-3

여기에 간단한 코드가 있지만, 나눗셈이나 복잡한 곱셈은 없습니다.더블 플러스 정확성 상실

그러나 어떤 경우에는 i의 값이 정확하지 않습니다. .79999999 또는 .600000001입니다.

왜 이런 일이 발생 했습니까? 정확한 코드가 어떻게 바뀌나요?

+5

보십시오. – chris

+0

아마도 프로그래밍에서 가장 답답한 질문입니다. 즉, 결과를 반올림하거나 정수 산술을 사용해야합니다. printf ("% .1f % n", i)'를 대신 사용해보십시오. 주 :'i <= 1'도 이상적입니다. –

답변

2

과 같은 특수 클래스가 있습니다. 부동 소수점 숫자는 정확하게 표현되지 않으며 정밀도를 잃습니다. 부동 소수점 숫자는 정확한 없기 때문에

for (int i=1; i<=10; i+=1) { 
     System.out.println("%.f", (double)i/10); 
} 
+0

이것은 "0 0 0 0 0 0 0 0 1"을 출력합니다 - 캐스팅을 float 또는 double에 추가해야합니다. – resueman

2

double은 정확하지 않습니다. 이는 유한 정밀도를 유지하도록 설계되었습니다.

정확한 "두 배"를

사용 BigDecimal :

BigDecimal d = new BigDecimal(".1"); 
for (BigDecimal i= d; ! i.equals(BigDecimal.ONE) ; i = i.add(d) { 
    System.out.println(i); 
} 
1

문제가 해결됩니다 루프 내부 int 사용 :

for (int i=1;i<=10;i++) { 
    System.out.println(i*0.1); 
} 

이 소수 분수 정밀도를 잃을 수 있기 때문에, 그들이있어 무슨 일이 일어나고 정확하게 표현되지 않았습니다.
자세한 내용은 What Every Computer Scientist Should Know About Floating-Point Arithmetic을 알고 싶을 수 있습니다.

+2

Downvoter, 제가 잘못한 것을 알려주십시오. 우리 모두는 우리의 실수로부터 배우기를 원합니다. – Maroun

+0

링크는 이론적으로 질문에 대답 할 수 있지만 여기에 답의 핵심 부분을 포함하고 참조 용 링크를 제공하는 것이 바람직합니다 (http://meta.stackexchange.com/q/8259). – JJJ

+0

@Juhana 링크가 답변을 제공합니다. IMHO에서 붙여 넣기 부분을 복사 할 필요가 없습니다. 그것을 읽으면 OP 질문에 답할 것입니다. 이것이 downvoting에 대한 좋은 이유라고 생각하지 않습니다. – Maroun

1

이것은 잘 알려진 속성 인 double입니다.
상점 번호를 0.x * 2^y (또는 1.x * 2^x) 형식으로 두 배로 늘립니다.
모든 정수가 정확하게 표현 될 수있는 것은 아니며 가장 중요한 것은
모든 소수 부분이 정확히으로 표시 될 수있는 것은 아닙니다.

여기에 BigDecimal과 같은 것을 사용해야합니다.

0

이것은 부동 소수점 연산 때문입니다. 정확한 값을 원하면 BigDecimal

0
for (double i = .1; i <= 1; i += .1) { 
    System.out.println(BigDecimal.valueOf(i).setScale(1, RoundingMode.HALF_UP)); 
}