2016-12-08 4 views
0

저는 자바를 배우기 시작한 숙련 된 PHP 개발자입니다. 나는 지금 약간의 린다 과정을 따라 가고 있으며 나는 여전히 초기 단계이다. 나는 사용자 입력을 요구하고 간단한 계산과 물건을하는 샘플 프로그램을 작성하고있다.Java 부서가 고장난 이유는 무엇입니까?

어제 나는이 상황에 걸쳐 온 :

double result = 1/2; 

을 내 원시인의 뇌와 내가 result == 0.5을 생각하지만, 아니, 자바 것이다. Apparantly 1/2 == 0.0. 네, 피연산자 중 하나를 double로 변경하면 결과도 double이됩니다.

이것은 실제로 두려워합니다. 나는 도울 수 없지만 이것이 매우 부러 졌다고 생각한다. 정수 나누기가 정수가된다고 생각하는 것은 매우 순진합니다. 나는 그것이 드물게 심지어 경우라고 생각한다.

그러나 자바가 널리 사용되고 '왜 자바의 부서가 고장 났는가?' 어떤 결과도 나오지 않을 것입니다. 아마도 틀렸을 것입니다.

내 질문은 :

  1. 왜 분열이처럼 행동 하는가?
  2. 그런 마법/부두/예기치 않은 행동을 찾을 수있는 곳은 어디입니까?
+2

1과 2는 정수이므로 1.0, 1f를 사용하거나 암시 적 캐스트를 수행하십시오. 이것은 설계 상으로는 이와 같이 동작하며, 정수 연산을 다룰 때마다 이것을 기대합니다. [Here] (http://ideone.com/MZIyBm)는 시도 할 수있는 몇 가지 옵션입니다. –

+0

느슨한 언어 (php)에서 강력한 형식의 언어 (java)로 가다 보면, 달리 명시하지 않는 한 정수가 정수로 유지된다는 사실에 익숙해 져야합니다. –

+0

왜 downvote? 나는 그 질문이 분명히 진술되었다고 생각한다. 다른 방법을 생각하면 알려 주시면 업데이트하겠습니다. –

답변

3

PHP 개발자처럼 생각하고 있습니다. PHP는 dynamically typed 언어입니다. 즉, 런타임에 유형을 추론하므로 분수는 논리적으로 정수를 생성 할 수 없으므로 double (또는 float)을 나눗셈 연산에서 가져온 것입니다.

, 100/50100/45 나에게 2을 제공하는 것처럼, 2 날 다시 제공 strongly typed 언어, 정수는 정수로 나눈 그래서 다시 정수를 얻을 수는 자바, C, C++, C# 및 다른 언어, 100/45이기 때문에 실제로 2.2222..., (정수 나누기) 전체 숫자를 얻으려면 자릿수를 자르고 2 얻을.

강하게 입력 된 언어에서 결과를 원하는대로 나타내려면 명시 적 (또는 내재적)이어야합니다. 따라서 나누기 연산에서 매개 변수 중 하나를 double 또는 float로 설정하면됩니다. 부동 소수점 나누기 (백분율을 제공).

그래서 자바에서, 당신이 중 하나를 수행 할 수있는 분수 번호를 얻기 위해 다음 없습니다 :

double result = 1.0/2; 
double result = 1f/2; 
double result = (float)1/2; 

부조화가 될 수있는 강력한 형식의 정적 언어 느슨한 타입, 동적 언어에서가는, 그러나 더있다 겁 먹을 필요가있다. 입력을 넘어서는 유효성 검사를 추가로 수행해야한다는 것을 이해하고 유형을 확인해야합니다. 자바 PHP에서가는

, 당신은 같은 것을하지 수 있습니다 알고 있어야합니다 :

$result = "2.0"; 
$result = "1.0"/$result; 
echo $result * 3; 

는 PHP,이 출력 1.5 ((1/2)*3 == 1.5 이후)을 생산하는 것입니다,하지만 자바,

String result = "2.0"; 
result = "1.0"/result; 
System.out.println(result * 1.5); 

문자열을 나눌 수 없으므로 오류가 발생합니다 (숫자가 아님).

희망이 도움이 될 수 있습니다.

+1

정확히. Java로 문자열을 나눌 수는 없지만 PHP에서는 문제가 없습니다! –

+0

좋아, 그럼 내가 배운 것은 기본적으로 다음과 같다. 1. 의도적으로 설계된 것이고, 2. 바람직한 행동이다. 내 결론 : 동의하고 받아들입니다. –

+0

@DennisHaarbrink .. 꽤 많이 :) # 2. 점에 추가 할 예정이지만 ... PHP (또는 루아, 펄, 자바 스크립트 등)와 같은 동적 언어에는 아무 것도 없지만 언어의 한계 등을 이해하는 것은 없습니다. 중요한 것은 ** 제한이 거기에있는 이유는 자바가'unsigned int '를 가지지 않는 것처럼 더 견고한 응용 프로그램을 만들 수 있도록 도와줍니다. 그래서 +/- 2.1 백만보다 큰 값을 유지하고자한다면 'long '을 사용할 필요가있다. – txtechhelp

0

나는 이것에 대해 전문가가 아니지만 연산자가 정수 산술을 수행하는 방법을 정의했기 때문이라고 생각합니다. 자바는 두 가지 모두 정수라고보고 있기 때문에 결과를 계산하기 위해 정수 나누기를 사용합니다. 이 "나누기"메서드에 두 개의 int를 입력하고 나누기 연산자가 오버로드되어이 정수 나누기를 수행합니다. 그렇지 않은 경우 Java는 오버로드 된 메서드에서 매번 두 번 캐스팅을 수행해야합니다. 어쨌든 이전에 캐스팅을 수행 할 수 없다면 본질적으로 쓸모가 없습니다.

5

Java는 강력한 형식의 언어이므로 표현식의 값 유형을 알아야합니다.

1은 ...없는 경우 int (2로), 그래서 1/2 1과 2의 정수 나눗셈은, 그래서 결과는 int로서 0이다. 그런 다음 결과는 해당하는 double 값으로 변환되므로 0.0입니다.

정수 나누기는 부동 소수점 나누기와 다릅니다 (자연수 구분은 실수 나누기와 다릅니다).

+1

좋은 질문은 바이트 분할이 바이트로 나타나지 않는 이유입니다. – lexicore

+0

@lexicore가 제기 한 질문에 대해 통찰력을 가진 사람이 있습니까? –

+0

@DennisHaarbrink 추가 질문으로 질문했습니다. http://stackoverflow.com/questions/41034555/why-byte-and-short-division-results-in-int-in-java – lexicore

0

C++로 시도하면 결과가 동일하다는 것을 알 수 있습니다. 이유는 변수에 값을 할당하기 전에 값을 계산해야하기 때문입니다. 입력 한 숫자 (1과 2)는 정수이므로 메모리 할당은 정수 여야합니다. 그런 다음 분단은 정수에 따라 수행되어야합니다. 그 후에는 double로 캐스팅하여 0.0이됩니다.

0

왜 사업부는 이와 같이 행동합니까?

언어 사양이 그런 식으로 정의했기 때문에.

그런 마법/부두/예상치 못한 동작을 찾을 수있는 곳은 어디입니까?

기본적으로 언어 사양에서 완벽하게 정의 된 "마법/부두"를 사용하기 때문에 답변은 "모든 곳"입니다.

그래서 실제로 Java에서이 디자인 결정이 있었던 이유는 질문입니다. 내 견지에서 int 부서의 결과는 int입니다. 강력한 형식의 언어에 대한 완벽한 설계 결정입니다. 순수 int 산술 연산이 자주 사용되므로 int 나누기가 float 또는 double이되므로 결과가 좋지 않을 수 있습니다.