remquo, remquof, remquol
| Definiert in Header <math.h> |
||
| float remquof( float x, float y, int *quo ); |
(1) | (seit C99) |
| double remquo( double x, double y, int *quo ); |
(2) | (seit C99) |
| long double remquol( long double x, long double y, int *quo ); |
(3) | (seit C99) |
| Definiert in Header <tgmath.h> |
||
| #define remquo( x, y, quo ) |
(4) | (seit C99) |
remquol aufgerufen. Andernfalls, wenn ein Nicht-Zeiger-Argument vom ganzzahligen Typ oder vom Typ double ist, wird remquo aufgerufen. Andernfalls wird remquof aufgerufen.Inhalt |
[bearbeiten] Parameter
| x, y | - | Gleitkommazahlen |
| quo | - | Zeiger auf einen ganzzahligen Wert, in dem das Vorzeichen und einige Bits von x/y gespeichert werden. |
[bearbeiten] Rückgabewert
Bei Erfolg wird der Gleitkomma-Rest der Division x/y wie in remainder definiert zurückgegeben und in *quo das Vorzeichen und mindestens drei der niedrigstwertigen Bits von x/y gespeichert (formal wird ein Wert gespeichert, dessen Vorzeichen das Vorzeichen von x/y ist und dessen Betrag kongruent modulo 2n
zum Betrag des ganzzahligen Quotienten von x/y ist, wobei n eine implementierungsdefinierte Ganzzahl größer oder gleich 3 ist).
Wenn y null ist, ist der Wert, der in *quo gespeichert wird, nicht spezifiziert.
Wenn ein Domänenfehler auftritt, wird ein implementierungsabhängiger Wert zurückgegeben (NaN, wo unterstützt).
Wenn ein Bereichsfehler aufgrund von Unterlauf auftritt, wird das korrekte Ergebnis zurückgegeben, wenn Subnormale unterstützt werden.
Wenn y null ist, aber kein Domänenfehler auftritt, wird null zurückgegeben.
[bearbeiten] Fehlerbehandlung
Fehler werden wie in math_errhandling angegeben gemeldet.
Ein Domänenfehler kann auftreten, wenn y Null ist.
Wenn die Implementierung IEEE-Gleitkomma-Arithmetik (IEC 60559) unterstützt,
- Der aktuelle Rundungsmodus hat keine Auswirkung.
- FE_INEXACT wird niemals ausgelöst.
- Wenn x ±∞ ist und y nicht NaN ist, wird NaN zurückgegeben und FE_INVALID ausgelöst.
- Wenn y ±0 ist und x nicht NaN ist, wird NaN zurückgegeben und FE_INVALID ausgelöst.
- Wenn entweder x oder y NaN ist, wird NaN zurückgegeben.
[bearbeiten] Anmerkungen
POSIX schreibt vor, dass ein Domänenfehler auftritt, wenn x unendlich ist oder y null ist.
Diese Funktion ist nützlich bei der Implementierung periodischer Funktionen mit einer Periode, die exakt als Gleitkommazahl darstellbar ist: Bei der Berechnung von sin(πx) für ein sehr großes x kann der direkte Aufruf von sin zu einem großen Fehler führen. Wenn jedoch das Funktionsargument zuerst mit remquo reduziert wird, können die niedrigwertigen Bits des Quotienten verwendet werden, um das Vorzeichen und das Oktant des Ergebnisses innerhalb der Periode zu bestimmen, während der Rest verwendet werden kann, um den Wert mit hoher Präzision zu berechnen.
Auf einigen Plattformen wird diese Operation von der Hardware unterstützt (und beispielsweise auf Intel-CPUs hinterlässt FPREM1 genau 3 Bits Präzision im Quotienten).
[bearbeiten] Beispiel
#include <fenv.h> #include <math.h> #include <stdio.h> #ifndef __GNUC__ #pragma STDC FENV_ACCESS ON #endif double cos_pi_x_naive(double x) { const double pi = acos(-1); return cos(pi * x); } // the period is 2, values are (0;0.5) positive, (0.5;1.5) negative, (1.5,2) positive double cos_pi_x_smart(double x) { const double pi = acos(-1); int extremum; double rem = remquo(x, 1, &extremum); extremum = (unsigned)extremum % 2; // keep 1 bit to determine nearest extremum return extremum ? -cos(pi * rem) : cos(pi * rem); } int main(void) { printf("cos(pi * 0.25) = %f\n", cos_pi_x_naive(0.25)); printf("cos(pi * 1.25) = %f\n", cos_pi_x_naive(1.25)); printf("cos(pi * 1000000000000.25) = %f\n", cos_pi_x_naive(1000000000000.25)); printf("cos(pi * 1000000000001.25) = %f\n", cos_pi_x_naive(1000000000001.25)); printf("cos(pi * 1000000000000.25) = %f\n", cos_pi_x_smart(1000000000000.25)); printf("cos(pi * 1000000000001.25) = %f\n", cos_pi_x_smart(1000000000001.25)); // error handling feclearexcept(FE_ALL_EXCEPT); int quo; printf("remquo(+Inf, 1) = %.1f\n", remquo(INFINITY, 1, &quo)); if (fetestexcept(FE_INVALID)) puts(" FE_INVALID raised"); }
Mögliche Ausgabe
cos(pi * 0.25) = 0.707107
cos(pi * 1.25) = -0.707107
cos(pi * 1000000000000.25) = 0.707123
cos(pi * 1000000000001.25) = -0.707117
cos(pi * 1000000000000.25) = 0.707107
cos(pi * 1000000000001.25) = -0.707107
remquo(+Inf, 1) = -nan
FE_INVALID raised[bearbeiten] Referenzen
- C23-Standard (ISO/IEC 9899:2024)
- 7.12.10.3 Die remquo-Funktionen (S. TBD)
- 7.25 Typ-generische Mathematik <tgmath.h> (S. TBD)
- F.10.7.3 Die remquo-Funktionen (S. TBD)
- C17-Standard (ISO/IEC 9899:2018)
- 7.12.10.3 Die remquo-Funktionen (S. 186)
- 7.25 Typ-generische Mathematik <tgmath.h> (S. 272-273)
- F.10.7.3 Die remquo-Funktionen (S. 385)
- C11-Standard (ISO/IEC 9899:2011)
- 7.12.10.3 Die remquo-Funktionen (S. 255)
- 7.25 Typ-generische Mathematik <tgmath.h> (S. 373-375)
- F.10.7.3 Die remquo-Funktionen (S. 529)
- C99-Standard (ISO/IEC 9899:1999)
- 7.12.10.3 Die remquo-Funktionen (S. 236)
- 7.22 Typ-generische Mathematik <tgmath.h> (S. 335-337)
- F.9.7.3 Die remquo-Funktionen (S. 465)
[bearbeiten] Siehe auch
| (C99) |
berechnet Quotient und Rest der ganzzahligen Division (Funktion) |
| (C99)(C99) |
berechnet den Rest der Gleitkommadivision (Funktion) |
| (C99)(C99)(C99) |
berechnet den vorzeichenbehafteten Rest der Gleitkommadivision (Funktion) |
| C++-Dokumentation für remquo
| |