Namespaces
Variants

std:: remquo, std:: remquof, std:: remquol

From cppreference.net
Common mathematical functions
Nearest integer floating point operations
(C++11)
(C++11)
(C++11) (C++11) (C++11)
Floating point manipulation functions
(C++11) (C++11)
(C++11)
(C++11)
Classification and comparison
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Types
(C++11)
(C++11)
(C++11)
Macro constants
Definiert im Header <cmath>
(1)
float remquo ( float x, float y, int * quo ) ;

double remquo ( double x, double y, int * quo ) ;

long double remquo ( long double x, long double y, int * quo ) ;
(seit C++11)
(bis C++23)
constexpr /* floating-point-type */

remquo ( /* floating-point-type */ x,

/* floating-point-type */ y, int * quo ) ;
(seit C++23)
float remquof ( float x, float y, int * quo ) ;
(2) (seit C++11)
(constexpr seit C++23)
long double remquol ( long double x, long double y, int * quo ) ;
(3) (seit C++11)
(constexpr seit C++23)
Definiert im Header <cmath>
template < class Arithmetic1, class Arithmetic2 >

/* common-floating-point-type */

remquo ( Arithmetic1 x, Arithmetic2 y, int * quo ) ;
(A) (seit C++11)
(constexpr seit C++23)
1-3) Berechnet den Gleitkomma-Rest der Divisionsoperation x / y wie die std::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. Die Bibliothek stellt Überladungen von std::remquo für alle cv-unqualifizierten Gleitkommatypen als Typ der Parameter x und y bereit. (seit C++23)
A) Zusätzliche Überladungen werden für alle anderen Kombinationen arithmetischer Typen bereitgestellt.

Inhaltsverzeichnis

Parameter

x, y - Gleitkomma- oder Ganzzahlwerte
quo - Zeiger auf int zum Speichern des Vorzeichens und einiger Bits von x / y

Rückgabewert

Bei Erfolg gibt den Gleitkomma-Rest der Division x / y zurück, wie in std::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 spezifiziert.

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 Periode, die exakt als Fließkommawert darstellbar ist: bei der Berechnung von sin(πx) für ein sehr großes x kann der direkte Aufruf von std::sin zu einem großen Fehler führen, aber wenn das Funktionsargument zuerst mit std::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 lässt FPREM1 bei Abschluss genau 3 Bits Präzision im Quotienten zurück).

Die zusätzlichen Überladungen müssen nicht exakt wie (A) bereitgestellt werden. Sie müssen lediglich sicherstellen, dass für ihr erstes Argument num1 und zweites Argument num2 :

  • Falls num1 oder num2 den Typ long double hat, dann hat std :: remquo ( num1, num2, quo ) denselben Effekt wie std :: remquo ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) , quo )
    .
  • Andernfalls, falls num1 und/oder num2 den Typ double oder einen Ganzzahltyp hat, dann hat std :: remquo ( num1, num2, quo ) denselben Effekt wie std :: remquo ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) , quo )
    .
  • Andernfalls, falls num1 oder num2 den Typ float hat, dann hat std :: remquo ( num1, num2, quo ) denselben Effekt wie std :: remquo ( static_cast < float > ( num1 ) ,
    static_cast < float > ( num2 ) , quo )
    .
(bis C++23)

Falls num1 und num2 arithmetische Typen haben, dann hat std :: remquo ( num1, num2, quo ) denselben Effekt wie std :: remquo ( static_cast < /*common-floating-point-type*/ > ( num1 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) , quo )
, wobei /*common-floating-point-type*/ der Gleitkommatyp mit dem höchsten Gleitkomma-Konvertierungsrang und dem höchsten Gleitkomma-Konvertierungsunterrang zwischen den Typen von num1 und num2 ist; Argumente vom Ganzzahltyp werden als mit demselben Gleitkomma-Konvertierungsrang wie double betrachtet.

Falls kein solcher Gleitkommatyp mit dem höchsten Rang und Unterrang existiert, dann führt Überladungsauflösung nicht zu einem verwendbaren Kandidaten aus den bereitgestellten Überladungen.

(seit C++23)

Beispiel

#include <cfenv>
#include <cmath>
#include <iostream>
#ifndef __GNUC__
#pragma STDC FENV_ACCESS ON
#endif
const double pi = std::acos(-1); // oder std::numbers::pi seit C++20
double cos_pi_x_naive(double x)
{
    return std::cos(pi * x);
}
// Die Periode ist 2, Werte sind (0;0.5) positiv, (0.5;1.5) negativ, (1.5,2) positiv
double cos_pi_x_smart(double x)
{
    int quadrant;
    double rem = std::remquo(x, 1, &quadrant);
    quadrant = static_cast<unsigned>(quadrant) % 2; // Die Periode ist 2.
    return quadrant == 0 ?  std::cos(pi * rem)
                         : -std::cos(pi * rem);
}
int main()
{
    std::cout << std::showpos
              << "naiv:\n"
              << "  cos(pi * 0.25) = " << cos_pi_x_naive(0.25) << '\n'
              << "  cos(pi * 1.25) = " << cos_pi_x_naive(1.25) << '\n'
              << "  cos(pi * 2.25) = " << cos_pi_x_naive(2.25) << '\n'
              << "smart:\n"
              << "  cos(pi * 0.25) = " << cos_pi_x_smart(0.25) << '\n'
              << "  cos(pi * 1.25) = " << cos_pi_x_smart(1.25) << '\n'
              << "  cos(pi * 2.25) = " << cos_pi_x_smart(2.25) << '\n'
              << "naiv:\n"
              << "  cos(pi * 1000000000000.25) = "
              << cos_pi_x_naive(1000000000000.25) << '\n'
              << "  cos(pi * 1000000000001.25) = "
              << cos_pi_x_naive(1000000000001.25) << '\n'
              << "smart:\n"
              << "  cos(pi * 1000000000000.25) = "
              << cos_pi_x_smart(1000000000000.25) << '\n'
              << "  cos(pi * 1000000000001.25) = "
              << cos_pi_x_smart(1000000000001.25) << '\n';
    // Fehlerbehandlung
    std::feclearexcept(FE_ALL_EXCEPT);
    int quo;
    std::cout << "remquo(+Inf, 1) = " << std::remquo(INFINITY, 1, &quo) << '\n';
    if (fetestexcept(FE_INVALID))
        std::cout << "  FE_INVALID ausgelöst\n";
}

Mögliche Ausgabe:

naiv:
  cos(pi * 0.25) = +0.707107
  cos(pi * 1.25) = -0.707107
  cos(pi * 2.25) = +0.707107
smart:
  cos(pi * 0.25) = +0.707107
  cos(pi * 1.25) = -0.707107
  cos(pi * 2.25) = +0.707107
naiv:
  cos(pi * 1000000000000.25) = +0.707123
  cos(pi * 1000000000001.25) = -0.707117
smart:
  cos(pi * 1000000000000.25) = +0.707107
  cos(pi * 1000000000001.25) = -0.707107
remquo(+Inf, 1) = -nan
  FE_INVALID ausgelöst

Siehe auch

berechnet Quotient und Rest der ganzzahligen Division
(Funktion)
(C++11) (C++11)
Rest der Gleitkomma-Divisionsoperation
(Funktion)
(C++11) (C++11) (C++11)
vorzeichenbehafteter Rest der Divisionsoperation
(Funktion)
C-Dokumentation für remquo