2012-07-29 4 views
0

다음 코드에서 T1과 T3가 다른 방법은 없습니다. 확실히 내 계산기는 그렇지 않다고 말합니다. 중이 샘플 프로그램에서 그것은 단지에서 System.out.println 아니다자바에서 수학 문제가 왜 발생합니까?

-1702967296 
86400000 
2592000000 

:

public class longTest { 
    public static final long T1 = 24 * 60 * 60 * 1000 * 30; 
    public static final long T2 = 24 * 60 * 60 * 1000; 
    public static final long T3 = T2 * 30; 

    public static void main(String[] args) { 

     System.out.println(T1); 
     System.out.println(T2); 
     System.out.println(T3); 
    } 
} 

그래서 내가 왜의 출력을 얻을 않습니다. 변수에 일식과 마우스가있는 T1을 사용하면 동일한 값을 나타내는 광택이 생깁니다. int이 2,147,483,647보다 클 수 없습니다 때문에

자바 버전 "1.6.0_33"OSX

+1

정수 오버플로 –

+1

* "Java에서 근본적으로 수학이 잘못 되었습니까?"- 물론 아닙니다! –

+0

@Shark * 정수 * 오버 플로우. 누군가가 그것을 개조 할 때까지 가치가 오래 가지 않습니다. – EJP

답변

6

편집증 - 안드로이드는 말하기를 int 오버플로 문제입니다. T3가 다른 이유를 이해하려면 아래를 참조하십시오.

public static final long T1 = 24 * 60 * 60 * 1000 * 30; 

모든 숫자는 여기 그래서 이것은

public static final long T1 = (long) (24 * 60 * 60 * 1000 * 30); 

int 부품 오버 플로우과 동일 int s에, 그래서 long에 대한 암시 적 캐스트는 정밀도의 손실을 방지하기 위해 너무 늦게 도착한다.

public static final long T2 = 24 * 60 * 60 * 1000; 

에서 동일한 그러나이 그에 맞는 작은 수의 양쪽 32 비트 int와 64 비트의 long (양수 값으로 31 비트).

public static final long T3 = T2 * 30; 

이은 int 의해 long이 그래서 서로 다른 값을 가지는 이유 인 64 비트 산술 연산을 수행 곱한다.
은 여기 암시 long가 조기에 정밀도의 손실을 방지하는 것입니다

public static final long T3 = T2 * (long) 30; 

에 해당합니다.

8

당신은 오버 플로우가 있어요. 최종 값은 long 유형의 범위를 벗어나지 않지만 숫자가으로 입력되지 않으면 int으로 처리됩니다.

이 시도 :

public class LongTest { 

    public static final long T1 = 24L * 60 * 60 * 1000 * 30; 
    public static final long T2 = 24L * 60 * 60 * 1000; 
    public static final long T3 = T2 * 30; 

    public static void main(String[] args) { 
     System.out.println(T1); 
     System.out.println(T2); 
     System.out.println(T3); 
    } 
} 
+7

'long'을 표시하려면'l' 대신'L'을 사용하십시오. 소문자'l'은 많은 터미널 폰트에서'1'과 매우 흡사합니다. 반면'L'은 그렇지 않습니다. –

+0

사실 아주 좋은 지적입니다. +1 – rtheunissen

+1

실제로 이것은 너무 좋음 public static final long T1 = 24L * 60 * 60 * 1000 * 30; – user1258245

1

이다 T1에, 모든 숫자가 정수이기 때문에, 수학 연산이 다음 긴 할당, 정수에서 수행되도록. T3은 Long에 Integer를 곱하고 있으므로 수학을 수행하는 동안 Long을 사용하므로 결과가 예상대로됩니다.

는 문제를 해결하려면, 당신은 오래 당신의 숫자 상수를 변경해야 음수를 얻을 이유

public class longTest { 
    public static final long T1 = 24L * 60L * 60L * 1000L * 30L; 
    public static final long T2 = 24 * 60 * 60 * 1000; 
    public static final long T3 = T2 * 30; 

    public static void main(String[] args) { 

     System.out.println(T1); 
     System.out.println(T2); 
     System.out.println(T3); 
    } 

} 

가 이해하기 : 그것은 가장 큰 양수에 도달 할 때 (2^31 -1) , 가장 큰 음수 (-2^31)로 감싸고 거기에서 올라갑니다. 이 포장은 여러 번 발생할 수 있습니다, 그래서 당신이 할 때

public static final int T4 = 100 * 100 * 100 * 100 * 100;// = 1410065408 WHAT!?!? 

당신은 정수가 가질 수있는 것보다 더 큰 10 억 달러를 얻을. 이 2,147,483,647에 도달하면 그래서, 그것은 다음 .. 등등 -2,147,483,648하고 간다 그래서 10 억이이 같은 간다 :

2,147,483,647

을 (네거티브로 이월을, 우리는 여전히 7,852,516,353 가고 남아있다)

-2,147,483,648 는

(나머지 3,557,549,058 추가)

-2,147,483,648 (우리는 아직도 갈 3557549057가 다시 악재로 이월)

2,147,483,647이 (Integer.MAX_INT까지 모든 방법을 계산)

그리고 지금 우리가 가지고있는 것 : 1,410,065,408

관련 문제