Namespaces
Variants

fma, fmaf, fmal

From cppreference.net
< c ‎ | numeric ‎ | math
Common mathematical functions
Functions
Basic operations
(C99)
fma
(C99)
(C99)
(C99) (C99) (C99) (C23)
Maximum/minimum operations
Exponential functions
Power functions
Trigonometric and hyperbolic functions
Nearest integer floating-point
(C99) (C99) (C99)
(C23) (C23) (C23) (C23)
Floating-point manipulation
Narrowing operations
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
Quantum and quantum exponent
Decimal re-encoding functions
Total order and payload functions
Classification
Error and gamma functions
(C99)
(C99)
(C99)
(C99)
Types
Macro constants
Special floating-point values
Arguments and return values
Error handling
Fast operation indicators
Definiert im Header <math.h>
float fmaf ( float x, float y, float z ) ;
(1) (seit C99)
double fma ( double x, double y, double z ) ;
(2) (seit C99)
long double fmal ( long double x, long double y, long double z ) ;
(3) (seit C99)
#define FP_FAST_FMA  /* implementation-defined */
(4) (seit C99)
#define FP_FAST_FMAF /* implementation-defined */
(5) (seit C99)
#define FP_FAST_FMAL /* implementation-defined */
(6) (seit C99)
Definiert im Header <tgmath.h>
#define fma( x, y, z )
(7) (seit C99)
1-3) Berechnet ( x * y ) + z als ob mit unendlicher Präzision und nur einmal gerundet, um in den Ergebnistyp zu passen.
4-6) Falls die Makrokonstanten FP_FAST_FMA , FP_FAST_FMAF oder FP_FAST_FMAL definiert sind, wertet die entsprechende Funktion fma , fmaf oder fmal schneller aus (zusätzlich zur höheren Genauigkeit) als der Ausdruck x * y + z für double -, float - bzw. long double -Argumente. Falls definiert, evaluieren diese Makros zum Integerwert 1 .
7) Typgenerisches Makro: Wenn ein Argument den Typ long double hat, wird fmal aufgerufen. Andernfalls, wenn ein Argument Ganzzahltyp oder den Typ double hat, wird fma aufgerufen. Andernfalls wird fmaf aufgerufen.

Inhaltsverzeichnis

Parameter

x, y, z - Gleitkommawerte

Rückgabewert

Bei Erfolg wird der Wert von ( x * y ) + z zurückgegeben, als ob mit unendlicher Präzision berechnet und einmal gerundet, um in den Ergebnistyp zu passen (oder alternativ als einzelne ternäre Gleitkommaoperation berechnet).

Wenn ein Bereichsfehler aufgrund von Überlauf auftritt, ±HUGE_VAL , ±HUGE_VALF , oder ±HUGE_VALL wird zurückgegeben.

Wenn ein Bereichsfehler aufgrund von Unterlauf auftritt, wird der korrekte Wert (nach Rundung) zurückgegeben.

Fehlerbehandlung

Fehler werden gemeldet, wie in math_errhandling festgelegt.

Wenn die Implementierung IEEE-Gleitkommaarithmetik (IEC 60559) unterstützt,

  • Wenn x null ist und y unendlich ist oder wenn x unendlich ist und y null ist, und
    • wenn z kein NaN ist, wird NaN zurückgegeben und FE_INVALID ausgelöst,
    • wenn z ein NaN ist, wird NaN zurückgegeben und FE_INVALID kann ausgelöst werden.
  • Wenn x * y ein exaktes Unendlich ist und z ein Unendlich mit entgegengesetztem Vorzeichen ist, wird NaN zurückgegeben und FE_INVALID ausgelöst.
  • Wenn x oder y NaN sind, wird NaN zurückgegeben.
  • Wenn z NaN ist, und x * y nicht 0 * Inf oder Inf * 0 ist, wird NaN zurückgegeben (ohne FE_INVALID ).

Hinweise

Diese Operation wird in der Hardware üblicherweise als fused multiply-add CPU-Befehl implementiert. Falls hardwareunterstützt, wird erwartet, dass die entsprechenden FP_FAST_FMA * Makros definiert sind, jedoch nutzen viele Implementierungen den CPU-Befehl selbst dann, wenn die Makros nicht definiert sind.

POSIX legt fest , dass der Fall, in dem der Wert x * y ungültig ist und z ein NaN ist, ein Domänenfehler ist.

Aufgrund seiner unendlich genauen Zwischenpräzision ist fma ein häufig verwendeter Baustein für andere korrekt gerundete mathematische Operationen, wie sqrt oder sogar die Division (sofern nicht vom Prozessor bereitgestellt, z.B. Itanium ).

Wie bei allen Gleitkomma-Ausdrücken kann der Ausdruck ( x * y ) + z als kombinierte Multiplikations-Addition kompiliert werden, es sei denn, #pragma STDC FP_CONTRACT ist deaktiviert.

Beispiel

#include <fenv.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
// #pragma STDC FENV_ACCESS ON
int main(void)
{
    // demo the difference between fma and built-in operators
    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);
    // fma use in double-double arithmetic
    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);
    // error handling
    feclearexcept(FE_ALL_EXCEPT);
    printf("fma(+Inf, 10, -Inf) = %f\n", fma(INFINITY, 10, -INFINITY));
    if (fetestexcept(FE_INVALID))
        puts("    FE_INVALID raised");
}

Mögliche Ausgabe:

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
**Übersetzungshinweise:** - HTML-Tags, Attribute und Code-Blöcke wurden unverändert belassen - C++-spezifische Begriffe (fma, FE_INVALID, etc.) wurden nicht übersetzt - Kommentare im Code wurden nicht übersetzt (wie angefordert) - Nur die sichtbaren UI-Texte und Beschreibungen wurden ins Deutsche übersetzt - Technische Präzision wurde beibehalten

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 7.12.13.1 Die fma-Funktionen (S.: TBD)
  • 7.25 Typgenerische Mathematik <tgmath.h> (S.: TBD)
  • F.10.10.1 Die fma-Funktionen (S.: TBD)
  • C17-Standard (ISO/IEC 9899:2018):
  • 7.12.13.1 The fma functions (S. 188-189)
  • 7.25 Type-generic math <tgmath.h> (S. 272-273)
  • F.10.10.1 The fma functions (S. 386)
  • C11-Standard (ISO/IEC 9899:2011):
  • 7.12.13.1 Die fma-Funktionen (S. 258)
  • 7.25 Typgenerische Mathematik <tgmath.h> (S. 373-375)
  • F.10.10.1 Die fma-Funktionen (S. 530)
  • C99-Standard (ISO/IEC 9899:1999):
  • 7.12.13.1 The fma functions (S. 239)
  • 7.22 Type-generic math <tgmath.h> (S. 335-337)
  • F.9.10.1 The fma functions (S. 466)

Siehe auch

Berechnet den vorzeichenbehafteten Rest der Gleitkomma-Divisionsoperation
(Funktion)
(C99) (C99) (C99)
Berechnet den vorzeichenbehafteten Rest sowie die letzten drei Bits der Divisionsoperation
(Funktion)