2012-11-24 3 views
5

보다 큰 값을 보유 문자열에서 두 번 구문 분석 : 1.7976931348623157E308 모든 것의 언급 한 값에 대해는 다음과 같은 자바 코드를 고려 Double.MaxValue

String toParse = "1.7976931348623157E308"; //max value of a double in java   
double parsed = Double.parseDouble(toParse); 
System.out.println(parsed); 

하는 것은 의미가 있습니다 하나는 올바른 출력을 얻을 수 있습니다.

이제 1.7976931348623158E308 (마지막 숫자는 E 증가하기 전까지)을 구문 분석하려고 시도하지만 여전히 최대 값이 콘솔에 인쇄됩니다!
1.7976931348623159E308을 구문 분석 한 후에 만 ​​(다시 마지막 숫자가 증가합니다) 큰 숫자는 Infinity이됩니다.
해당 음수 값에 대해 동일한 동작입니다.

... 8E308... 7E308으로 해석되며 Infinity이 아닌 이유는 무엇입니까?

+1

이 응용 프로그램과 관련성이 있습니까? – AlexWien

+1

나는 당신이 가장자리 사건으로 재미를 느끼고 있다고 생각한다. 소스 코드를 보셨습니까? –

+0

@AlexWien이 우연히 "우연히"우연히 발견했습니다. –

답변

9

parseDouble 문서의 SE 7 버전은 말한다 위해 valueOf 설명서를 참조합니다 또한 오버 플로우와 언더 플로우 행동으로 반올림 규칙 함축

하는 것으로, s의 정확한 값이 (MAX_VALUE + ulp (MAX_VALUE)/2)보다 크거나 같으면 double로 반올림하면 무한대가되고 s의 정확한 값이 크기가 충분히 작 으면 보다 또는 0 발생합니다 떠 반올림)/2 MIN_VALUE와 같다.

이 라운딩이 부동 IEEE 754의 근사값으로 반올림 규칙에 의해 두 번 입력하는 설명과 일관성이 소수점 연산

지수 제한을 무시하고 가장 가까운 부동 소수점 수를 먼저 계산 한 다음 지수가 맞는지 여부를 확인하여 변환을 수행했다고 상상해보십시오. Double.MAX_VALUE는 해당 규칙에서 가장 가까운 숫자입니다 저것 그것보다 엄하게 크다.

public class Test { 
     public static void main(String[] args) { 
     double ulp = Math.ulp(Double.MAX_VALUE); 
     System.out.println(ulp); 
     System.out.println(Double.MAX_VALUE); 
     System.out.println(Double.MAX_VALUE+ulp/2.0000000001); 
     System.out.println(Double.MAX_VALUE+ulp/2); 
     } 
    } 

그것은 출력 :

1.9958403095347198E292 
1.7976931348623157E308 
1.7976931348623157E308 
Infinity 

만들어 Double.MAX_VALUE에 반 ULP 변화를하지 않는 조금이라도 덜보다 뭔가를 추가

고려,이 정상 반올림 동작입니다 다음 프로그램을 확인하려면 그것. 절반의 ulp를 추가하면 무한대로 오버플로됩니다.

+0

+1 예제 코드는 내 머리를 감싸는 부분이었습니다! 고마워, 패트리샤 –

관련 문제