Java에서 float를 비교하고 있으며 가장 간단한 공식은 다음과 같습니다.
Math.abs(a - b) < THRESHOLD
차이의 임계 값으로 변수의 이름을 지정할 때 이름을 delta 또는 epsilon으로 지정해야 합니까? 특히, 부동 소수점 숫자가 나타낼 수있는 가장 작은 값에 대한 올바른 용어는 무엇입니까?
프로그래밍 언어라는 용어가 구체적입니까, 아니면 언어 전체에 보편적입니까?
Java에서 float를 비교하고 있으며 가장 간단한 공식은 다음과 같습니다.
Math.abs(a - b) < THRESHOLD
차이의 임계 값으로 변수의 이름을 지정할 때 이름을 delta 또는 epsilon으로 지정해야 합니까? 특히, 부동 소수점 숫자가 나타낼 수있는 가장 작은 값에 대한 올바른 용어는 무엇입니까?
프로그래밍 언어라는 용어가 구체적입니까, 아니면 언어 전체에 보편적입니까?
답변:
수학 및 공학 분야의 Epsilon
일반적으로 수학 및 공학에서 :
엡실론은 귀하의 경우에 더 적절 해 보입니다.
컴퓨터 과학의 Epsilon
특히 컴퓨터 과학 용어 엡실론도 지칭 기계 espilon 차이 측정 1.0f
및보다 확실히 크다 작은 플로트 1.0f
. 후자의 숫자는 1.00000011920928955078125f
Java의 부동 소수점 수이며 다음 을 사용하여 계산할 수 있습니다.
float f = Float.intBitsToFloat(Float.floatToIntBits(1f) + 1);
머신 엡실론의 정의는 위에서 설명한 엡실론의 일반적인 사용과 일치합니다.
수레 비교
그러나 "근접성"에 대한 플로트를 비교하기 전에 그 규모에 대한 아이디어가 필요합니다. 두 개의 매우 크고 아마도 다른 플로트는 같을 수 있습니다.
9223372036854775808f == 9223372036854775808f + 1000000000f; //this is true!
역으로, 기계 엡실론 "단지"에 의해 다른 두 개의 작은 플로트 사이에 가능한 많은 플로트 값 (및 수십 배)이있을 수 있습니다. 아래 예에서 small
와 사이에 10,000,000 개의 부동 소수점 값이 f
있지만 그 차이는 여전히 머신 엡실론보다 훨씬 낮습니다.
float small = Float.MIN_VALUE; // small = 1.4E-45
float f = Float.intBitsToFloat(Float.floatToIntBits(small) + 100000000); // f = 2.3122343E-35
boolean b = (f - small < 0.00000011920928955078125f); //true!
GlenH7의 답변 과 관련된 기사는 플로트 비교를 추가로 조사하고 이러한 문제를 극복하기위한 몇 가지 솔루션을 제안합니다.
질문에 직접 대답하기 위해이라는 용어를 사용하려고합니다 epsilon
. 보다 정확하게는 machine epsilon
일반적인 사용법이지만 "machine"이 떨어지고 그냥 사용합니다 epsilon
.
내 로컬 사본을 float.h
보면 다음과 같습니다.
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
#define LDBL_EPSILON DBL_EPSILON /* smallest such that 1.0+LDBL_EPSILON != 1.0 */
그리고 관련된 의견은 엡실론이 당신이 말하는 용어임을 분명히합니다.
그러나 다른 외부 참조를 사용 epsilon
하여 올바른 용어인지 확인할 수도 있습니다. 여기 , 여기 , 여기 및 마지막으로이 SO 쿼리 태그 조합을 참조 하십시오 . 인용 할 IEEE 754 표준에 대한 직접적인 참조를 찾을 수 없었습니다.
Valve의 Bruce Dawson이 작성한 블로그 기사 에서 플로팅 포인트 값 을 비교하여 제안한 비교를 사용하고 싶지 않은 이유에 대한 통찰력을 얻으십시오.
이 기사에는 약간의 정보가 들어 있지만 여기에서 가장 관련있는 스 니펫입니다.
플로트를 평등에 대해 비교하는 것이 나쁜 생각이라면 차이가 일부 오류 범위 또는 엡실론 값 내에 있는지 확인하는 방법은 다음과 같습니다.
bool isEqual = fabs(f1 – f2) <= epsilon;
이 계산을 통해 우리는 두 플로트가 동일하다고 생각하기에 충분히 가깝다는 개념을 표현할 수 있습니다. 그러나 엡실론에 어떤 가치를 사용해야합니까?
위의 실험을 감안할 때 우리는 1.19e-7f 정도의 합계에서 오류를 사용하려는 유혹을받을 수 있습니다. 실제로 float.h에는 정확한 값을 가진 정의가 있으며 FLT_EPSILON이라고합니다.
분명히 그렇습니다. 헤더 파일 신이 말했고 FLT_EPSILON은 하나의 진정한 엡실론입니다!
그것이 쓰레기라는 것을 제외하고. 1.0과 2.0 사이의 숫자의 경우 FLT_EPSILON은 인접한 float 간의 차이를 나타냅니다. 1.0보다 작은 숫자의 경우 FLT_EPSILON의 엡실론이 너무 빨리 커지고, 작은 숫자로 FLT_EPSILON이 비교하는 숫자보다 클 수 있습니다!
Dawson은 플로트를 비교하고 이와 같은 매우 작은 값을 처리 할 때 관련된 복잡성에 대해 몇 가지 다른 고려 사항을 검토하므로 나머지 게시물을 읽는 것이 좋습니다.
simplest formula
비교 와 관련이 있다고 생각했습니다 . 많은 사람들이 그 접근법을 첫 번째 시도로 사용했으며, Dawson의 기사를 포함 시켰습니다. 왜냐하면 비교가 얼마나 까다로운 지에 대한 미묘한 차이가 있기 때문입니다. 그래서 나는 질문에 직접 대답하고 왜 그렇게 사용하지 않는지 지적하려고 노력했습니다.
이것은 오류 함수입니다. 절대 오차는 일반적으로 일부 수량 x에 대해 ε (엡실론) 또는 Δ x 라고합니다 .
ε = | 예상-실제 |
Δ x = | x 0 − x |
상대 오차는 때때로 η (eta) 라고합니다 .
η = | 1-실제 / 예상 |
프로그래밍 목적 absoluteError
및 relativeError
(또는 일부 약어) 더 설명 적입니다. 오류가 특정 값보다 작다고 주장하려면 해당 값을 간단히 임계 값 또는 공차 라고합니다 .
보다:
"공차"라고 부릅니다.
어쩌면 그것은 수학적으로 올바른 용어는 아니지만, "델타"나 "엡실론"이 사용하기에 좋은 변수 이름이 아니라는 것을 나에게 암시합니다.
내 경험상 실제로 코드를 읽는 사람들에게 적합한 식별자 이름을 사용하는 것이 좋습니다. 독자가 그것이 무엇을 의미하는지 이해하기 위해 위키 백과에서 찾아야한다는 것을 의미한다면 완벽하게 올바른 이름은 무엇입니까?