무시 하기 쉬 운 자바 정수 넘 침 오류: 연도 차 이 를 정확하게 얻 을 수 없 는 이유
예 를 들 어 우 리 는 지금 두 시간 점 의 연도 차 이 를 계산 할 계획 이다. 비록 많은 함수 가 우 리 를 도와 이 문 제 를 해결 할 수 있 지만 (예 를 들 어 먼저 연도 치 를 꺼 내 고 상쇄 하 는 것).그러나 두 시간 사이 의 수치 차 (시간 유형의 데 이 터 는 컴퓨터 에서 실제로 long 형의 수치 로 저장 되 기 때 문) 를 통 해 이러한 시간 차 를 직접 계산 할 수 있다.
잘못된 코드 를 보 여 줍 니 다.
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2008-05-24 00:00:00");
Date date2 = sdf.parse("2009-05-24 00:00:00");
System.out.println((date2.getTime()-date.getTime())/((long)(1000*3600*24*365)));
그 중에서 이 코드 의 가장 주요 한 사상 은 시간 점 2 (date 2) 의 수 치 를 이용 하여 시간 점 1 (date) 의 수 치 를 뺀 다음 에 1000 을 나 누 어 밀리초 수 치 를 초 로 바 꾸 는 것 이다.3600 * 24 로 나 누 어 하늘 로 전환;마지막 으로 365 로 나 누 어 성인 으로 전환한다.코드 의 논리 적 으로 오류 가 없습니다. (물론 엄 밀 히 말 하면 365 일 또는 366 일 을 구분 해 야 하기 때문에 연 차 를 계산 하 는 것 은 추천 하지 않 습 니 다) 하지만 실행 할 때 항상 오류 가 발생 하여 얻 은 결 과 는 21 입 니 다!눈치 빠 른 사람 은 두 시점 의 연 차 가 1 년 이라는 것 을 단번에 알 수 있 을 것 이다.그래서 마지막 줄 코드 를 다음 과 같이 바 꾸 는 것 을 고려 합 니 다.
System.out.println((date2.getTime()-date.getTime())/((long)(1000*3600*24)));
발견 하면 정확 한 결 과 를 얻 을 수 있다. 366 일.그래서 다시 코드 를 다음 과 같이 바 꿉 니 다.
System.out.println((date2.getTime()-date.getTime())/((long)(1000*3600*24))/365);
발견 하면 정확 한 결 과 를 얻 을 수 있다. 1 년.그러나 코드 를 첫 번 째 상황 으로 바 꾸 면 계산 오류 가 발생 한 것 으로 나 타 났 다.이런 상황 에서 가장 유력 한 원인 은 변수의 넘 침 문제 이다.우 리 는 1 년 의 밀리초 수 를 계산 해 볼 수 있다.
1000*3600*24*365 = 31536000000 ms/year
원래 int 형 변수의 최대 치 를 훨씬 초과 했다. 2147483647 이다.그래서 계산 코드 를 다음 과 같이 바 꾸 면 결 과 를 정확하게 얻 을 수 있 습 니 다.
System.out.println((date2.getTime()-date.getTime())/(((long)(3600*24*1000))*((long)(365))));
보아하니 컴퓨터 의 지원 능력 과 프로 그래 밍 언어의 발전 으로 인해 우 리 는 각종 변 수 를 편리 하 게 사용 할 수 있 지만 가끔 은 이런 유형의 변수 가 지원 하 는 범 위 를 주의해 서 범 위 를 초과 하여 이상 하 게 넘 치 는 오 류 를 초래 하지 않도록 해 야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.