Namespaces
Variants

remquo, remquof, remquol

From cppreference.net
< c ‎ | numeric ‎ | math
Common mathematical functions
Functions
Basic operations
remquo
(C99)
(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 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 im Header <tgmath.h>
#define remquo( x, y, quo )
(4) (seit C99)
1-3) Berechnet den Gleitkomma-Rest der Divisionsoperation x / y wie die remainder() Funktion. Zusätzlich werden das Vorzeichen und mindestens die letzten drei Bits von x / y in quo gespeichert, was ausreicht, um den Oktanten des Ergebnisses innerhalb einer Periode zu bestimmen.
4) Typgenerisches Makro: Wenn ein Nicht-Pointer-Argument den Typ long double hat, wird remquol aufgerufen. Andernfalls, wenn ein Nicht-Pointer-Argument ganzzahligen Typ oder den Typ double hat, wird remquo aufgerufen. Andernfalls wird remquof aufgerufen.

Inhaltsverzeichnis

Parameter

x, y - Gleitkommawerte
quo - Zeiger auf einen ganzzahligen Wert zum Speichern des Vorzeichens und einiger Bits von x / y

Rückgabewert

Bei Erfolg gibt es den Gleitkomma-Rest der Division x / y zurück, wie in remainder definiert, und speichert in * quo das Vorzeichen und mindestens drei der niederwertigsten Bits von x / y (formal: speichert einen Wert, dessen Vorzeichen dem Vorzeichen von x / y entspricht und dessen Betrag kongruent modulo 2 n
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 in * quo gespeicherte Wert nicht spezifiziert.

Wenn ein Domänenfehler auftritt, wird ein implementierungsdefinierter Wert zurückgegeben (NaN, sofern 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.

Fehlerbehandlung

Fehler werden gemeldet, wie in math_errhandling festgelegt.

Ein Domänenfehler kann auftreten, wenn y null ist.

Wenn die Implementierung IEEE-Gleitkommaarithmetik (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

Hinweise

POSIX erfordert 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 exakt als Fließkommawert darstellbaren Periode: 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, aber wenn das Funktionsargument zuerst mit remquo reduziert wird, können die niederwertigen Bits des Quotienten verwendet werden, um das Vorzeichen und die Oktante des Ergebnisses innerhalb der Periode zu bestimmen, während der Rest zur Berechnung des Werts mit hoher Genauigkeit verwendet werden kann.

Auf einigen Plattformen wird dieser Vorgang durch Hardware unterstützt (und zum Beispiel auf Intel-CPUs FPREM1 belässt genau 3 Bits Genauigkeit im Quotienten).

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

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 7.12.10.3 Die remquo-Funktionen (S: TBD)
  • 7.25 Typgenerische 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 Typgenerische 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 Typgenerische 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 Typgenerische Mathematik <tgmath.h> (S. 335-337)
  • F.9.7.3 Die remquo-Funktionen (S. 465)

Siehe auch

berechnet Quotient und Rest der Ganzzahldivision
(Funktion)
(C99) (C99)
berechnet den Rest der Gleitkomma-Divisionsoperation
(Funktion)
berechnet den vorzeichenbehafteten Rest der Gleitkomma-Divisionsoperation
(Funktion)