2012-10-31 10 views
0

내 응용 프로그램에서 부동 소수점 연산을 많이 수행하고 있으며 부동 소수점 연산이 100 % 정확하지는 않지만 부동 소수점 연산 결과는 아직 인쇄하지 않은 것을 알고 있습니다. 올바르게 형식을 지정하는 방법을 찾으십시오. 예를 들어JAVA 부동 소수점 연산

0.1 + 0.1 = 0.19999999999999999999999

으로, Math.sin (Math.PI로는) = 1.2246E16 대신 내가 찾고 1.000000000000000001

같은

물건 0 그 결과를 가져 와서 적절한 반올림 값 (문자열 형식)을 얻는 일반적인 방법

0.1 + 0.1 = 0.19999999999999999999999 -> 0.2이 하나

으로, Math.sin (Math.PI로) = 1.2246E16 올림 필요 -> 0

1.000000000000000001과 같은 물건 -> 1; 이 반올림이 필요합니다.

결과가 동일 할 경우 결과가 1.1234567891234567 또는 1.33333333333333 인 경우와 같이 데이터가 손실되는 것을 방지하고 싶습니다.

+1

http://floating-point-gui.de/ – BalusC

+1

불가능합니다. (0.1 + 0.1의 결과이므로) '0.1999999999999'를 반올림해야하는지 ('0.2 - 0.000000000001'? – rolve

+0

'System.out.println (0.1+ 0.1)'0.2 "를 산출하지만 부수적으로는 – DNA

답변

1

서식을 사용하지 않으려면 인쇄하기 전에 결과를 고정 된 정밀도로 반올림하고 Java에서 표현 오류를 숨기려면 소량의 반올림을 수행하면됩니다.

6 소수점 이하 자릿수

public static double round6(double d) { 
    return Math.round(d * 1e6)/1e6; 
} 

round()의 결과 및 1e6 정확하게 표현 될 수있다. 또한 "IEEE 754은 올바른 반올림이 필요합니다. 즉, 반올림 결과는 무한 정밀도의 산술 연산을 사용하여 값을 계산 한 다음 반올림 한 것입니다."가장 가까운 표현할 수있는 값은 표현 오류입니다. Java의 toString()은 가장 가까운 십진수로 표현할 수있는 값을 가진 double 값을 가지고 있다고 가정합니다.

) (가지는 Double.toString이 값을 전달할 때, 0.1의 실제 값이

System.out.println(new BigDecimal(0.1)); 

인쇄

0.1000000000000000055511151231257827021181583404541015625 

하지만, 그것은 0.1이 이중으로 전환 될 것이고, 그래서이 무엇이 해야하는 것으로 판단 표시됩니다.

현재 자바 6에서는 최소 자릿수를 사용하지 않는 버그가 있습니다.

0.0010 0.0020 0.0030 0.0040 0.0050 0.0060 0.0070 0.0080 0.0090 

및 Java 7 인쇄

자바
for (int i = 1; i <= 9; i++) 
    System.out.print(i/1000.0 + " "); 

6 인쇄

이 경우, 나는를 사용하여 성능이 중요하지 않으며 경우에 나는 종종의 printf를 사용
0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009 

ByteBuffer를 고정 된 정밀도로 효과적으로 작성하는 커스텀 루틴 (효과적으로 반올림) 이것은 어떤 객체도 생성하지 않으므로 빠릅니다.

결과가 동일 할 경우 결과가 1.1234567891234567 또는 1.33333333333333 인 경우에도 데이터 손실을 방지하고 싶습니다.

그런 경우 표시해야 할 때까지 결과를 반올림하지 마십시오.

+0

왜 반올림 오류가 발생하지 않습니까? –

+0

어디서 그런지 모릅니다. 이것은 정수를 다른 정수로 나눌 때 얻을 수있는 반올림 오류의 한계가 있기 때문입니다. –

+0

@TobiasRitzau 적은 ​​손짓으로 대답했습니다;) –

1

예 : System.out.printf("%.6f", myFloat)을 사용하는 형식.

+0

printf를 사용하지 않음 – aviran

+0

@aviran printf를 사용하고 싶지 않은 이유는 무엇입니까? btw +1 –

+0

'String.format()'은 같은 인자를 취하고 당신에게 다른 유사한 포맷 옵션이있는'String'을 제공합니다. –

0

소수를 잃지 않으려면 float 대신 BigDecimal을 사용하십시오. 천천히하지만 더 정확한.

+0

BigDecimal은 sin/cos/log/ln과 같은 함수에서 어떻게 작동합니까? 정확한 계산에 관한 것이 아니라 결과 1.9999로 살 수 있지만 다시 인쇄 할 때 2.0, 모든 제안을 원하십니까? – aviran