부동 소수점 연산을 가정 할 때 OP의 알고리즘은 우수하며 a
과 b
의 크기가 크게 다를 때 정밀도 손실로 인해 항상 a + f * (b - a)
보다 우수합니다. 예를 들어
: lint2
잘못 0.0 반환 반면 그 예에서
// OP's algorithm
float lint1 (float a, float b, float f) {
return (a * (1.0f - f)) + (b * f);
}
// Algebraically simplified algorithm
float lint2 (float a, float b, float f) {
return a + f * (b - a);
}
, 32 비트 추정은 lint1(1.0e20, 1.0, 1.0)
올바르게 1.0 반환 수레.
피연산자의 수가 크게 다른 경우 정밀도 손실의 대부분은 더하기 및 빼기 연산자에 있습니다. 위의 경우에 범인은 b - a
의 뺄셈이고 a + f * (b - a)
의 덧셈입니다. 추가하기 전에 구성 요소가 완전히 곱 해져서 OP 알고리즘에 문제가 발생하지 않습니다. A = 1E20, B = 1 경우에 대해
여기 상이한 결과의 일례이다. 테스트 프로그램 :
#include <stdio.h>
#include <math.h>
float lint1 (float a, float b, float f) {
return (a * (1.0f - f)) + (b * f);
}
float lint2 (float a, float b, float f) {
return a + f * (b - a);
}
int main() {
const float a = 1.0e20;
const float b = 1.0;
int n;
for (n = 0; n <= 1024; ++ n) {
float f = (float)n/1024.0f;
float p1 = lint1(a, b, f);
float p2 = lint2(a, b, f);
if (p1 != p2) {
printf("%i %.6f %f %f %.6e\n", n, f, p1, p2, p2 - p1);
}
}
return 0;
}
출력 약간 조정 서식 : A와 B는 상당히 다를 때 지수
f lint1 lint2 lint2-lint1
0.828125 17187500894208393216 17187499794696765440 -1.099512e+12
0.890625 10937500768952909824 10937499669441282048 -1.099512e+12
0.914062 8593750447104196608 8593749897348382720 -5.497558e+11
0.945312 5468750384476454912 5468749834720641024 -5.497558e+11
0.957031 4296875223552098304 4296874948674191360 -2.748779e+11
0.972656 2734375192238227456 2734374917360320512 -2.748779e+11
0.978516 2148437611776049152 2148437474337095680 -1.374390e+11
0.986328 1367187596119113728 1367187458680160256 -1.374390e+11
0.989258 1074218805888024576 1074218737168547840 -6.871948e+10
0.993164 683593798059556864 683593729340080128 -6.871948e+10
1.000000 1 0 -1.000000e+00
이 때문에 정밀도가 손실 등가 알고리즘 아니다. OP의 알고리즘은 항상 더 나은 선택입니다. 예를 들어,이 대답의 알고리즘은'lerp (-16.0e30, 16.0, 1.0)'에 대해 OP의 알고리즘이 생성하는 올바른 결과 인 16 대신에 0을 반환합니다. 정밀도 손실은 'a'가'f * (b-a)'보다 상당히 크고'(b-a)'의 빼기 연산자에서 더하기 연산자에서 발생합니다. –
원래의 알고리즘은 성능 측면에서도 큰 손실이 없습니다. FP 곱셈은 FP 덧셈보다 훨씬 빠르며, f가 0과 1 사이의 값을 갖게된다면, (1-f)에 대한 최적화가 가능합니다 . – Sneftel
@Sneftel :''1-f''에 대한 최적화에 대해 자세히 설명해 주시겠습니까? 나는 그런 상황에 처해 있으며 궁금하다. D –