std:: fma, std:: fmaf, std:: fmal
|
헤더 파일에 정의됨
<cmath>
|
||
| (1) | ||
|
float
fma
(
float
x,
float
y,
float
z
)
;
double
fma
(
double
x,
double
y,
double
z
)
;
|
(C++11부터)
(C++23까지) |
|
|
constexpr
/* floating-point-type */
fma
(
/* floating-point-type */
x,
|
(C++23부터) | |
|
float
fmaf
(
float
x,
float
y,
float
z
)
;
|
(2) |
(C++11부터)
(C++23부터 constexpr) |
|
long
double
fmal
(
long
double
x,
long
double
y,
long
double
z
)
;
|
(3) |
(C++11부터)
(C++23부터 constexpr) |
|
#define FP_FAST_FMA /* implementation-defined */
|
(4) | (C++11부터) |
|
#define FP_FAST_FMAF /* implementation-defined */
|
(5) | (C++11부터) |
|
#define FP_FAST_FMAL /* implementation-defined */
|
(6) | (C++11부터) |
|
헤더 파일에 정의됨
<cmath>
|
||
|
template
<
class
Arithmetic1,
class
Arithmetic2,
class
Arithmetic3
>
/* common-floating-point-type */
|
(A) |
(C++11부터)
(C++23부터 constexpr) |
std::fma
의 오버로드를 제공합니다.
(C++23부터)
std::fma
는 각각
double
,
float
, 및
long
double
인수에 대해 표현식
x
*
y
+
z
보다 (더 정밀할 뿐만 아니라) 더 빠르게 평가됩니다. 정의된 경우, 이러한 매크로는 정수
1
로 평가됩니다.
목차 |
매개변수
| 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
(
fma
,
fmaf
,
fmal
)
는 추가적으로
FE_INVALID
을 반환하도록 명시된 상황들이 도메인 오류임을 지정합니다.
무한한 중간 정밀도 덕분에,
std::fma
는 올바르게 반올림된 다른 수학 연산들, 예를 들어
std::sqrt
또는 심지어 (CPU에서 제공되지 않는 경우, 예를 들어
Itanium
에서처럼) 나눗셈과 같은 연산들의 공통 구성 요소입니다.
모든 부동 소수점 표현식과 마찬가지로, x * y + z 표현식은 #pragma STDC FP_CONTRACT 가 off 상태가 아닌 한 fused multiply-add로 컴파일될 수 있습니다.
추가 오버로드는 반드시 (A) 와 동일하게 제공될 필요가 없습니다. 첫 번째 인수 num1 , 두 번째 인수 num2 , 그리고 세 번째 인수 num3 에 대해 다음을 보장하기에 충분하기만 하면 됩니다:
|
(C++23 이전) |
|
num1
,
num2
,
num3
가 산술 타입을 가지는 경우,
std
::
fma
(
num1, num2, num3
)
는 다음 코드와 동일한 효과를 가집니다:
std
::
fma
(
static_cast
<
/*common-floating-point-type*/
>
(
num1
)
,
가장 높은 등급과 하위 등급을 가지는 부동소수점 타입이 존재하지 않는 경우, 오버로드 해결 은 제공된 오버로드들 중에서 사용 가능한 후보를 결과로 내지 않습니다. |
(C++23부터) |
예제
#include <cfenv> #include <cmath> #include <iomanip> #include <iostream> #ifndef __GNUC__ #pragma STDC FENV_ACCESS ON #endif int main() { // fma와 기본 연산자의 차이점을 보여줌 const double in = 0.1; std::cout << "0.1 double is " << std::setprecision(23) << in << " (" << std::hexfloat << in << std::defaultfloat << ")\n" << "0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), " << "or 1.0 if rounded to double\n"; const double expr_result = 0.1 * 10 - 1; const double fma_result = std::fma(0.1, 10, -1); std::cout << "0.1 * 10 - 1 = " << expr_result << " : 1 subtracted after intermediate rounding\n" << "fma(0.1, 10, -1) = " << std::setprecision(6) << fma_result << " (" << std::hexfloat << fma_result << std::defaultfloat << ")\n\n"; // fma는 double-double 연산에서 사용됨 const double high = 0.1 * 10; const double low = std::fma(0.1, 10, -high); std::cout << "in double-double arithmetic, 0.1 * 10 is representable as " << high << " + " << low << "\n\n"; // 오류 처리 std::feclearexcept(FE_ALL_EXCEPT); std::cout << "fma(+Inf, 10, -Inf) = " << std::fma(INFINITY, 10, -INFINITY) << '\n'; if (std::fetestexcept(FE_INVALID)) std::cout << " FE_INVALID raised\n"; }
가능한 출력:
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
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
참고 항목
|
(C++11)
(C++11)
(C++11)
|
나눗셈 연산의 부호 있는 나머지
(함수) |
|
(C++11)
(C++11)
(C++11)
|
부호 있는 나머지 및 나눗셈 연산의 마지막 세 비트
(함수) |
|
C documentation
for
fma
|
|