std::nextafter, std::nextafterf, std::nextafterl, std::nexttoward, std::nexttowardf, std::nexttowardl
| Definiert in der Header-Datei <cmath> |
||
| (1) | ||
float nextafter( float from, float to ); double nextafter( double from, double to ); |
(seit C++11) (bis C++23) |
|
| constexpr /* gleitkommazahl-Typ */ nextafter( /* Gleitkommazahltyp */ from, |
(seit C++23) | |
| float nextafterf( float from, float to ); |
(2) | (seit C++11) (constexpr seit C++23) |
| long double nextafterl( long double from, long double to ); |
(3) | (seit C++11) (constexpr seit C++23) |
| (4) | ||
float nexttoward( float from, long double to ); double nexttoward( double from, long double to ); |
(seit C++11) (bis C++23) |
|
| constexpr /* gleitkommazahl-Typ */ nexttoward( /* Gleitkommazahltyp */ from, |
(seit C++23) | |
| float nexttowardf( float from, long double to ); |
(5) | (seit C++11) (constexpr seit C++23) |
| long double nexttowardl( long double from, long double to ); |
(6) | (seit C++11) (constexpr seit C++23) |
| Definiert in der Header-Datei <cmath> |
||
| template< class Arithmetic1, class Arithmetic2 > /* common-floating-point-type */ |
(A) | (seit C++11) (constexpr seit C++23) |
| template< class Integer > double nexttoward( Integer from, long double to ); |
(B) | (seit C++11) (constexpr seit C++23) |
Gibt den nächsten darstellbaren Wert von from in Richtung to zurück.
std::nextafter für alle cv-unqualifizierten Gleitkommatypen als Typ der Parameter from und to bereit.(seit C++23)|
Die Bibliothek stellt Überladungen von |
(seit C++23) |
std::nextafter Überladungen werden für alle anderen Kombinationen von arithmetischen Typen bereitgestellt.std::nexttoward Überladungen werden für alle Ganzzahltypen bereitgestellt, die als double behandelt werden.Inhalt |
[edit] Parameter
| from, to | - | Gleitkomma- oder Ganzzahlwerte |
[edit] Rückgabewert
Wenn keine Fehler auftreten, wird der nächste darstellbare Wert von from in Richtung to zurückgegeben. Wenn from gleich to ist, wird to zurückgegeben.
Wenn ein Bereichsfehler aufgrund von Überlauf auftritt, wird ±HUGE_VAL, ±HUGE_VALF oder ±HUGE_VALL zurückgegeben (mit demselben Vorzeichen wie from).
Wenn ein Bereichsfehler aufgrund von Unterlauf auftritt, wird das korrekte Ergebnis zurückgegeben.
[edit] Fehlerbehandlung
Fehler werden wie in math_errhandling beschrieben gemeldet.
Wenn die Implementierung IEEE-Gleitkomma-Arithmetik (IEC 60559) unterstützt,
- Wenn from endlich ist, aber das erwartete Ergebnis eine Unendlichkeit ist, werden FE_INEXACT und FE_OVERFLOW ausgelöst.
- Wenn from nicht gleich to ist und das Ergebnis subnormal oder Null ist, werden FE_INEXACT und FE_UNDERFLOW ausgelöst.
- In jedem Fall ist der zurückgegebene Wert unabhängig vom aktuellen Rundungsmodus.
- Wenn entweder from oder to NaN ist, wird NaN zurückgegeben.
[edit] Hinweise
POSIX spezifiziert, dass die Überlauf- und Unterlaufbedingungen Bereichsfehler sind (errno kann gesetzt werden).
IEC 60559 empfiehlt, dass from zurückgegeben wird, wenn from == to. Diese Funktionen geben stattdessen to zurück, was das Verhalten um Null konsistent macht: std::nextafter(-0.0, +0.0) gibt +0.0 zurück und std::nextafter(+0.0, -0.0) gibt -0.0 zurück.
std::nextafter wird typischerweise durch Manipulation der IEEE-Darstellung implementiert (glibc, musl).
Die zusätzlichen std::nextafter Überladungen müssen nicht exakt wie (A) bereitgestellt werden. Sie müssen nur ausreichen, um sicherzustellen, dass für ihr erstes Argument num1 und ihr zweites Argument num2
|
(bis C++23) |
|
Wenn num1 und num2 arithmetische Typen haben, dann hat std::nextafter(num1, num2) denselben Effekt wie std::nextafter(static_cast</*gemeinsamer-gleitkommazahltyp*/>(num1), Wenn kein solcher Gleitkommazahltyp mit dem höchsten Rang und Subrang existiert, dann führt die Überladungsauflösung nicht zu einem nutzbaren Kandidaten aus den bereitgestellten Überladungen. |
(seit C++23) |
Die zusätzlichen std::nexttoward Überladungen müssen nicht exakt wie (B) bereitgestellt werden. Sie müssen nur ausreichen, um sicherzustellen, dass für ihr Argument num vom Ganzzahltyp, std::nexttoward(num) denselben Effekt hat wie std::nexttoward(static_cast<double>(num)).
[edit] Beispiel
#include <cfenv> #include <cfloat> #include <cmath> #include <concepts> #include <iomanip> #include <iostream> int main() { float from1 = 0, to1 = std::nextafter(from1, 1.f); std::cout << "The next representable float after " << std::setprecision(20) << from1 << " is " << to1 << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat; float from2 = 1, to2 = std::nextafter(from2, 2.f); std::cout << "The next representable float after " << from2 << " is " << to2 << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat; double from3 = std::nextafter(0.1, 0), to3 = 0.1; std::cout << "The number 0.1 lies between two valid doubles:\n" << std::setprecision(56) << " " << from3 << std::hexfloat << " (" << from3 << ')' << std::defaultfloat << "\nand " << to3 << std::hexfloat << " (" << to3 << ")\n" << std::defaultfloat << std::setprecision(20); std::cout << "\nDifference between nextafter and nexttoward:\n"; long double dir = std::nextafter(from1, 1.0L); // first subnormal long double float x = std::nextafter(from1, dir); // first converts dir to float, giving 0 std::cout << "With nextafter, next float after " << from1 << " is " << x << '\n'; x = std::nexttoward(from1, dir); std::cout << "With nexttoward, next float after " << from1 << " is " << x << '\n'; std::cout << "\nSpecial values:\n"; { // #pragma STDC FENV_ACCESS ON std::feclearexcept(FE_ALL_EXCEPT); double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY); std::cout << "The next representable double after " << std::setprecision(6) << from4 << std::hexfloat << " (" << from4 << ')' << std::defaultfloat << " is " << to4 << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat; if (std::fetestexcept(FE_OVERFLOW)) std::cout << " raised FE_OVERFLOW\n"; if (std::fetestexcept(FE_INEXACT)) std::cout << " raised FE_INEXACT\n"; } // end FENV_ACCESS block float from5 = 0.0, to5 = std::nextafter(from5, -0.0); std::cout << "std::nextafter(+0.0, -0.0) gives " << std::fixed << to5 << '\n'; auto precision_loss_demo = []<std::floating_point Fp>(const auto rem, const Fp start) { std::cout << rem; for (Fp from = start, to, Δ; (Δ = (to = std::nextafter(from, +INFINITY)) - from) < Fp(10.0); from *= Fp(10.0)) std::cout << "nextafter(" << std::scientific << std::setprecision(0) << from << ", INF) gives " << std::fixed << std::setprecision(6) << to << "; Δ = " << Δ << '\n'; }; precision_loss_demo("\nPrecision loss demo for float:\n", 10.0f); precision_loss_demo("\nPrecision loss demo for double:\n", 10.0e9); precision_loss_demo("\nPrecision loss demo for long double:\n", 10.0e17L); }
Ausgabe
The next representable float after 0 is 1.4012984643248170709e-45 (0x1p-149)
The next representable float after 1 is 1.0000001192092895508 (0x1.000002p+0)
The number 0.1 lies between two valid doubles:
0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
and 0.1000000000000000055511151231257827021181583404541015625 (0x1.999999999999ap-4)
Difference between nextafter and nexttoward:
With nextafter, next float after 0 is 0
With nexttoward, next float after 0 is 1.4012984643248170709e-45
Special values:
The next representable double after 1.79769e+308 (0x1.fffffffffffffp+1023) is inf (inf)
raised FE_OVERFLOW
raised FE_INEXACT
std::nextafter(+0.0, -0.0) gives -0.000000
Precision loss demo for float:
nextafter(1e+01, INF) gives 10.000001; Δ = 0.000001
nextafter(1e+02, INF) gives 100.000008; Δ = 0.000008
nextafter(1e+03, INF) gives 1000.000061; Δ = 0.000061
nextafter(1e+04, INF) gives 10000.000977; Δ = 0.000977
nextafter(1e+05, INF) gives 100000.007812; Δ = 0.007812
nextafter(1e+06, INF) gives 1000000.062500; Δ = 0.062500
nextafter(1e+07, INF) gives 10000001.000000; Δ = 1.000000
nextafter(1e+08, INF) gives 100000008.000000; Δ = 8.000000
Precision loss demo for double:
nextafter(1e+10, INF) gives 10000000000.000002; Δ = 0.000002
nextafter(1e+11, INF) gives 100000000000.000015; Δ = 0.000015
nextafter(1e+12, INF) gives 1000000000000.000122; Δ = 0.000122
nextafter(1e+13, INF) gives 10000000000000.001953; Δ = 0.001953
nextafter(1e+14, INF) gives 100000000000000.015625; Δ = 0.015625
nextafter(1e+15, INF) gives 1000000000000000.125000; Δ = 0.125000
nextafter(1e+16, INF) gives 10000000000000002.000000; Δ = 2.000000
Precision loss demo for long double:
nextafter(1e+18, INF) gives 1000000000000000000.062500; Δ = 0.062500
nextafter(1e+19, INF) gives 10000000000000000001.000000; Δ = 1.000000
nextafter(1e+20, INF) gives 100000000000000000008.000000; Δ = 8.000000[edit] Siehe auch
| C-Dokumentation für nextafter
|