fma, fmaf, fmal
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
헤더 파일에 정의됨
<math.h>
|
||
|
float
fmaf
(
float
x,
float
y,
float
z
)
;
|
(1) | (C99부터) |
|
double
fma
(
double
x,
double
y,
double
z
)
;
|
(2) | (C99부터) |
|
long
double
fmal
(
long
double
x,
long
double
y,
long
double
z
)
;
|
(3) | (C99부터) |
|
#define FP_FAST_FMA /* implementation-defined */
|
(4) | (C99부터) |
|
#define FP_FAST_FMAF /* implementation-defined */
|
(5) | (C99부터) |
|
#define FP_FAST_FMAL /* implementation-defined */
|
(6) | (C99부터) |
|
헤더 파일에 정의됨
<tgmath.h>
|
||
|
#define fma( x, y, z )
|
(7) | (C99부터) |
FP_FAST_FMA
,
FP_FAST_FMAF
, 또는
FP_FAST_FMAL
가 정의된 경우, 해당 함수
fma
,
fmaf
, 또는
fmal
은 각각
x
*
y
+
z
표현식보다 (더 정밀할 뿐만 아니라) 더 빠르게 평가됩니다. 정의된 경우 이러한 매크로는 정수
1
로 평가됩니다.
fmal
이 호출됩니다. 그렇지 않고 인자 중 하나라도 정수 타입이거나
double
타입을 가지면
fma
가 호출됩니다. 그 외의 경우에는
fmaf
가 호출됩니다.
목차 |
매개변수
| x, y, z | - | 부동소수점 값 |
반환값
성공 시, 무한 정밀도로 계산된 후 결과 타입에 맞게 한 번 반올림된 ( x * y ) + z 의 값을 반환합니다 (또는 대안적으로 단일 삼항 부동 소수점 연산으로 계산됩니다).
오버플로로 인한 범위 오류가 발생하면,
±HUGE_VAL
,
±HUGE_VALF
, 또는
±HUGE_VALL
가 반환됩니다.
언더플로로 인한 범위 오류가 발생하면, 올바른 값(반올림 후)이 반환됩니다.
오류 처리
오류는
math_errhandling
에 명시된 대로 보고됩니다.
구현이 IEEE 부동 소수점 연산(IEC 60559)을 지원하는 경우,
-
만약
x
가 0이고
y
가 무한대이거나, 또는
x
가 무한대이고
y
가 0인 경우:
- 만약 z 가 NaN이 아니면 NaN이 반환되고 FE_INVALID 가 발생합니다,
- 만약 z 가 NaN이면 NaN이 반환되고 FE_INVALID 가 발생할 수 있습니다.
- 만약 x * y 가 정확한 무한대이고 z 가 반대 부호의 무한대인 경우, NaN이 반환되고 FE_INVALID 가 발생합니다.
- 만약 x 또는 y 가 NaN이면 NaN이 반환됩니다.
- 만약 z 가 NaN이고, x * y 가 0 * Inf 또는 Inf * 0 가 아닌 경우, NaN이 반환됩니다 ( FE_INVALID 없이).
참고 사항
이 연산은 일반적으로 하드웨어에서 fused multiply-add CPU 명령어로 구현됩니다. 하드웨어에서 지원되는 경우, 해당 FP_FAST_FMA * 매크로가 정의될 것으로 예상되지만, 많은 구현에서는 매크로가 정의되지 않은 경우에도 CPU 명령어를 사용합니다.
POSIX는 x * y 값이 유효하지 않고 z 가 NaN인 상황을 도메인 오류로 명시합니다.
무한한 중간 정밀도 덕분에,
fma
는
sqrt
또는 (CPU에서 제공되지 않는 경우, 예를 들어
Itanium
에서처럼) 나눗셈과 같은 다른 올바르게 반올림된 수학 연산들의 공통 구성 요소입니다.
모든 부동 소수점 표현식과 마찬가지로, ( x * y ) + z 표현식은 #pragma STDC FP_CONTRACT 가 꺼져 있지 않는 한 fused multiply-add로 컴파일될 수 있습니다.
예제
#include <fenv.h> #include <float.h> #include <math.h> #include <stdio.h> // #pragma STDC FENV_ACCESS ON int main(void) { // fma와 기본 연산자의 차이점을 보여줌 double in = 0.1; printf("0.1 double is %.23f (%a)\n", in, in); printf("0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3)," " or 1.0 if rounded to double\n"); double expr_result = 0.1 * 10 - 1; printf("0.1 * 10 - 1 = %g : 1 subtracted after " "intermediate rounding to 1.0\n", expr_result); double fma_result = fma(0.1, 10, -1); printf("fma(0.1, 10, -1) = %g (%a)\n", fma_result, fma_result); // double-double 연산에서의 fma 사용 printf("\nin double-double arithmetic, 0.1 * 10 is representable as "); double high = 0.1 * 10; double low = fma(0.1, 10, -high); printf("%g + %g\n\n", high, low); // 오류 처리 feclearexcept(FE_ALL_EXCEPT); printf("fma(+Inf, 10, -Inf) = %f\n", fma(INFINITY, 10, -INFINITY)); if (fetestexcept(FE_INVALID)) puts(" FE_INVALID raised"); }
가능한 출력:
0.1 double is 0.10000000000000000555112 (0x1.999999999999ap-4)
0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), or 1.0 if rounded to double
0.1 * 10 - 1 = 0 : 1 subtracted after intermediate rounding to 1.0
fma(0.1, 10, -1) = 5.55112e-17 (0x1p-54)
in double-double arithmetic, 0.1 * 10 is representable as 1 + 5.55112e-17
fma(+Inf, 10, -Inf) = -nan
FE_INVALID raised
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 7.12.13.1 The fma functions (p: TBD)
-
- 7.25 Type-generic math <tgmath.h> (p: TBD)
-
- F.10.10.1 The fma functions (p: TBD)
- C17 표준 (ISO/IEC 9899:2018):
-
- 7.12.13.1 fma 함수들 (p: 188-189)
-
- 7.25 타입-제네릭 수학 <tgmath.h> (p: 272-273)
-
- F.10.10.1 fma 함수들 (p: 386)
- C11 표준 (ISO/IEC 9899:2011):
-
- 7.12.13.1 The fma functions (p: 258)
-
- 7.25 Type-generic math <tgmath.h> (p: 373-375)
-
- F.10.10.1 The fma functions (p: 530)
- C99 표준 (ISO/IEC 9899:1999):
-
- 7.12.13.1 fma 함수들 (p: 239)
-
- 7.22 타입-제네릭 수학 <tgmath.h> (p: 335-337)
-
- F.9.10.1 fma 함수들 (p: 466)
참고 항목
|
(C99)
(C99)
(C99)
|
부동 소수점 나눗셈 연산의 부호 있는 나머지를 계산합니다
(함수) |
|
(C99)
(C99)
(C99)
|
부호 있는 나머지와 나눗셈 연산의 마지막 세 비트를 계산합니다
(함수) |
|
C++ documentation
for
fma
|
|