1. 실수 반올림

이미 논의한 것처럼 실수가 변수에 할당되면 int항상 가장 가까운 작은 정수로 내림됩니다. 소수 부분은 단순히 버려집니다.

그러나 소수를 어느 방향으로든 가장 가까운 정수로 반올림하거나 반올림해야 하는 상황을 쉽게 상상할 수 있습니다. 이 경우 어떻게 합니까?

이를 위해 그리고 많은 유사한 상황을 위해 Java에는 , 및 메서드가 Math있는 클래스가 있습니다 .round()ceil()floor()


Math.round()방법

Math.round()메서드는 숫자를 가장 가까운 정수로 반올림합니다.

long x = Math.round(real_number)

그러나 여기에 또 다른 뉘앙스가 있습니다. 이 메서드는 long정수( 가 아님 int)를 반환합니다. 실수는 매우 클 수 있기 때문에 Java 작성자는 Java에서 사용 가능한 가장 큰 정수 유형인 를 사용하기로 결정했습니다 long.

따라서 프로그래머가 결과를 변수에 할당하려는 경우 int프로그래머는 데이터 손실 가능성을 수락한다고 컴파일러에 명시적으로 표시해야 합니다(결과 숫자가 유형에 맞지 않는 경우 int).

int x = (int) Math.round(real_number)

예:

성명 결과
int x = (int) Math.round(4.1);
4
int x = (int) Math.round(4.5);
5
int x = (int) Math.round(4.9);
5

Math.ceil()방법

Math.ceil()메서드는 숫자를 정수 반올림합니다 . 다음은 예입니다.

성명 결과
int x = (int) Math.ceil(4.1);
5
int x = (int) Math.ceil(4.5);
5
int x = (int) Math.ceil(4.9);
5

Math.floor()방법

Math.floor()메서드는 숫자를 정수로 내림 합니다 . 다음은 예입니다.

성명 결과
int x = (int) Math.floor(4.1);
4
int x = (int) Math.floor(4.5);
4
int x = (int) Math.floor(4.9);
4

물론 숫자를 정수 로 내림 할 때는 단순히 유형 캐스트 ​​연산자를 사용하는 것이 더 쉽습니다.(int)

성명 결과
int x = (int) 4.9
4

이러한 이름을 기억하기 어렵다면 짧은 영어 수업이 도움이 될 것입니다.

  • Math수학을 의미
  • Round둥글다는 뜻
  • Ceiling천장을 의미
  • Floor바닥을 의미

2. 부동 소수점 수의 구조

이 유형은 에서 까지 double범위의 값을 저장할 수 있습니다 . (타입과 비교할 때) 이 엄청난 범위의 값은 타입(및 )이 정수 타입과 완전히 다른 내부 구조를 가지고 있다는 사실로 설명됩니다 . 내부적으로 유형은 값을 두 개의 숫자로 인코딩합니다. 첫 번째는 가수라고 하고 두 번째는 지수라고 합니다 .-1.7*10308+1.7*10308intdoublefloatdouble

숫자가 있고 변수 123456789에 저장 한다고 가정해 보겠습니다 double. 그렇게 하면 숫자가 로 변환되고 내부적으로 유형에 두 개의 숫자( 및 ) 가 저장됩니다 . 유효 숫자("숫자의 유효 부분" 또는 가수)는 빨간색으로 강조 표시되고 지수는 파란색으로 강조 표시됩니다.1.23456789*108double234567898

이 접근 방식을 사용하면 매우 큰 숫자와 매우 작은 숫자를 모두 저장할 수 있습니다. 그러나 숫자의 표현이 8바이트(64비트)로 제한되고 일부 비트가 지수 ( 가수 부호 및 지수 부호 포함)를 저장하는 데 사용되기 때문에 가수를 나타내는 데 사용할 수 있는 최대 자릿수는 15 입니다 .

이것은 실수가 어떻게 구성되는지에 대한 매우 간단한 설명입니다.


3. 실수로 작업할 때 정밀도 손실

실수로 작업할 때 실수는 정확하지 않다는 점을 항상 염두에 두십시오 . 10진수에서 2진수로 변환할 때 항상 반올림 오류변환 오류가 있을 수 있습니다 . 또한 가장 일반적인 오류 원인은 근본적으로 다른 축척에서 숫자를 더하거나 뺄 때 정밀도 손실 입니다.

이 마지막 사실은 초보 프로그래머에게는 약간 충격적입니다.

에서 빼면 가 됩니다 .1/109109109

근본적으로 다른 척도에서 숫자 빼기 설명
1000000000.000000000;
-         0.000000001;
 1000000000.000000000;
두 번째 숫자는 매우 작기 때문에 유효 숫자(회색으로 강조 표시됨)가 무시됩니다. 15 개의 유효 숫자는 주황색으로 강조 표시됩니다.

우리가 말할 수 있는 것은 프로그래밍이 수학과 같지 않다는 것입니다.


4. 실수를 비교할 때 함정

또 다른 위험은 실수를 비교할 때 프로그래머를 기다리는 것입니다. 반올림 오류가 누적될 수 있기 때문에 실수로 작업할 때 발생합니다. 그 결과 실수가 같을 것으로 예상되지만 그렇지 않은 상황이 있습니다. 또는 그 반대의 경우: 숫자는 다를 것으로 예상되지만 동일합니다.

예:

성명 설명
double a = 1000000000.0;
double b = 0.000000001;
double c = a - b;
변수의 값은 a 다음과 같습니다. 1000000000.0
변수의 값은 c 다음과 같습니다 1000000000.0
(변수의 숫자가 b 너무 작음).

위의 예에서 a및 은 c같지 않아야 하지만 동일합니다.

또는 다른 예를 들어 보겠습니다.

성명 설명
double a = 1.00000000000000001;
double b = 1.00000000000000002;
변수의 값은  다음 a 과 같습니다. 1.0
변수의 값은b1.0

5. 흥미로운 사실strictfp

Java 에는 다른 프로그래밍 언어에서는 볼 수 없는 특수 strictfp키워드( 엄격한 부동 소수점 ) 가 있습니다. 왜 필요한지 아십니까? 부동 소수점 숫자 연산의 정확도를 떨어뜨립니다 . 그것이 어떻게 되었는지에 대한 이야기는 다음과 같습니다.

자바 제작자:
우리는 Java가 매우 대중화되고 가능한 한 많은 장치에서 Java 프로그램을 실행하기를 정말로 원합니다. 그래서 우리는 모든 프로그램이 모든 유형의 장치에서 동일한 방식으로 실행되어야 한다는 자바 머신의 사양을 확인했습니다 !
인텔 프로세서 제조업체:
안녕 모두들! 우리는 프로세서를 개선했으며 이제 모든 실수는 프로세서 내부에서 8바이트 대신 10바이트를 사용하여 표현됩니다. 더 많은 바이트는 더 많은 유효 숫자를 의미합니다. 그게 무슨 뜻이야? 좋아요! 이제 과학적 계산이 더욱 정확해집니다!
초정밀 계산에 관련된 과학자 및 모든 사람:
시원한! 잘하셨어요. 좋은 소식!
자바 제작자:
안돼 안돼 너희들! 우리는 이미 모든 Java 프로그램이 모든 장치에서 동일하게 실행되어야 한다고 말했습니다 . Intel 프로세서 내부에서 10바이트 실수를 사용하는 기능을 강제로 비활성화합니다.
이제 모든 것이 다시 괜찮습니다! 우리에게 감사하지 마십시오.
초정밀 계산에 관련된 과학자 및 모든 사람:
당신은 완전히 미쳤습니까? 빨리 모든 것을 원래대로 되돌리십시오!
자바 제작자:
여러분, 이것은 여러분을 위한 것입니다! 상상해보세요. 모든 Java 프로그램이 모든 장치에서 동일한 방식으로 실행됩니다 . 정말 멋져요!
초정밀 계산에 관련된 과학자 및 모든 사람:
아니요. 전혀 멋지지 않습니다. 모든 것을 원래 상태로 빨리 되돌려 놓으십시오! 아니면 Java를 어디에 둘 것인지 알고 계십니까?
자바 제작자:
흠. 왜 바로 그렇게 말하지 않았습니까? 물론, 우리는 그것을 다시 넣을 것입니다.
최신 프로세서의 모든 기능을 사용할 수 있는 기능을 복원했습니다.
그건 그렇고... strictfp언어에 키워드도 특별히 추가했습니다. 함수 이름 앞에 쓰면 해당 함수 내부의 실수와 관련된 모든 작업이 모든 장치에서 똑같이 나쁠 것입니다 !