CodeGym /행동 /All lectures for KO purposes /실수 작업의 뉘앙스

실수 작업의 뉘앙스

All lectures for KO purposes
레벨 1 , 레슨 1081
사용 가능

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언어에 키워드도 특별히 추가했습니다. 함수 이름 앞에 쓰면 해당 함수 내부의 실수와 관련된 모든 작업이 모든 장치에서 똑같이 나쁠 것입니다 !
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION