std:: nextafter, std:: nextafterf, std:: nextafterl, std:: nexttoward, std:: nexttowardf, std:: nexttowardl
|
Definiert in Header
<cmath>
|
||
| (1) | ||
|
float
nextafter
(
float
from,
float
to
)
;
double
nextafter
(
double
from,
double
to
)
;
|
(seit C++11)
(bis C++23) |
|
|
constexpr
/* Gleitkommatyp */
nextafter
(
/* Gleitkommatyp */
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
/* Gleitkommatyp */
nexttoward
(
/* Gleitkommatyp */
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 im Header
<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 sind für alle anderen Kombinationen arithmetischer Typen bereitgestellt.
std::nexttoward
Überladungen werden für alle Ganzzahltypen bereitgestellt, die als
double
behandelt werden.
Inhaltsverzeichnis |
Parameter
| from, to | - | Gleitkomma- oder Ganzzahlwerte |
Rückgabewert
Wenn keine Fehler auftreten, wird der nächste darstellbare Wert von from in Richtung to zurückgegeben. Wenn from gleich to ist, dann wird to zurückgegeben.
Wenn ein Bereichsfehler aufgrund von Überlauf auftritt,
±HUGE_VAL
,
±HUGE_VALF
, oder
±HUGE_VALL
wird zurückgegeben (mit demselben Vorzeichen wie
from
).
Wenn ein Bereichsfehler aufgrund von Unterlauf auftritt, wird das korrekte Ergebnis zurückgegeben.
Fehlerbehandlung
Fehler werden gemeldet, wie in math_errhandling spezifiziert.
Wenn die Implementierung IEEE-Gleitkommaarithmetik (IEC 60559) unterstützt,
- wenn from endlich ist, aber das erwartete Ergebnis eine Unendlichkeit ist, löst FE_INEXACT und FE_OVERFLOW aus.
- wenn from nicht gleich to ist und das Ergebnis subnormal oder null ist, löst FE_INEXACT und FE_UNDERFLOW aus.
- in jedem Fall ist der zurückgegebene Wert unabhängig vom aktuellen Rundungsmodus.
- wenn entweder from oder to NaN ist, wird NaN zurückgegeben.
Hinweise
POSIX legt fest , 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 lediglich ausreichen, um sicherzustellen, dass für ihr erstes Argument
num1
und zweites Argument
num2
:
|
(bis C++23) |
|
Falls
num1
und
num2
arithmetische Typen haben, dann hat
std
::
nextafter
(
num1, num2
)
denselben Effekt wie
std
::
nextafter
(
static_cast
<
/*common-floating-point-type*/
>
(
num1
)
,
Falls kein solcher Gleitkommatyp mit dem höchsten Rang und Unterrang existiert, dann führt die Überladungsauflösung nicht zu einem verwendbaren 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 lediglich sicherstellen, dass für ihr Argument
num
vom Ganzzahltyp
std
::
nexttoward
(
num
)
dieselbe Wirkung hat wie
std
::
nexttoward
(
static_cast
<
double
>
(
num
)
)
.
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 << "Der nächstmögliche darstellbare Float nach " << std::setprecision(20) << from1 << " ist " << to1 << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat **Erklärung:** - HTML-Tags und Attribute wurden unverändert beibehalten - Der C++-spezifische Begriff `std::defaultfloat` wurde nicht übersetzt, da es sich um einen festen Bezeichner aus der C++-Standardbibliothek handelt - Die Formatierung und Struktur des Originalcodes bleibt vollständig erhalten; float from2 = 1, to2 = std::nextafter(from2, 2.f); std::cout << "Der nächstmögliche darstellbare Float nach " << from2 << " ist " << to2 << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat; double from3 = std::nextafter(0.1, 0), to3 = 0.1; std::cout << "Die Zahl 0.1 liegt zwischen zwei gültigen Doubles:\n" << std::setprecision(56) << " " << from3 << std::hexfloat << " (" << from3 << ')' << std::defaultfloat << "\nund " << to3 << std::hexfloat << " (" << to3 << ")\n" << std::defaultfloat << std::setprecision(20); std::cout << "\nUnterschied zwischen nextafter und nexttoward:\n"; long double dir = std::nextafter(from1, 1.0L); // erstes subnormales long double float x = std::nextafter(from1, dir); // wandelt zuerst dir in float um, ergibt 0 std::cout << "Mit nextafter, nächster Float nach " << from1 << " ist " << x << '\n'; x = std::nexttoward(from1, dir); std::cout << "Mit nexttoward, nächster Float nach " << from1 << " ist " << x << '\n'; std::cout << "\nSpezielle Werte:\n"; { // #pragma STDC FENV_ACCESS ON std::feclearexcept(FE_ALL_EXCEPT); double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY); std::cout << "Der nächste darstellbare Double-Wert nach " << std::setprecision(6) << from4 << std::hexfloat << " (" << from4 << ')' << std::defaultfloat << " ist " << to4 << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat; if (std::fetestexcept(FE_OVERFLOW)) std::cout << " FE_OVERFLOW ausgelöst\n"; if (std::fetestexcept(FE_INEXACT)) std::cout << " FE_INEXACT ausgelöst\n"; } // Ende des FENV_ACCESS-Blocks float from5 = 0.0, to5 = std::nextafter(from5, -0.0); std::cout << "std::nextafter(+0.0, -0.0) gibt " << 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) ergibt " << std::fixed << std::setprecision(6) << to << "; Δ = " << Δ << '\n'; }; precision_loss_demo("\nPräzisionsverlust-Demo für float:\n", 10.0f); precision_loss_demo("\nPräzisionsverlust-Demo für double:\n", 10.0e9); precision_loss_demo("\nPräzisionsverlust-Demo für long double:\n", 10.0e17L); }
Ausgabe:
Der nächstgrößere darstellbare Float-Wert nach 0 ist 1.4012984643248170709e-45 (0x1p-149)
Der nächstgrößere darstellbare Float-Wert nach 1 ist 1.0000001192092895508 (0x1.000002p+0)
Die Zahl 0.1 liegt zwischen zwei gültigen Doubles:
0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
und 0.1000000000000000055511151231257827021181583404541015625 (0x1.999999999999ap-4)
Unterschied zwischen nextafter und nexttoward:
Mit nextafter ist der nächste Float-Wert nach 0 gleich 0
Mit nexttoward ist der nächste Float-Wert nach 0 gleich 1.4012984643248170709e-45
Spezielle Werte:
Der nächstgrößere darstellbare Double-Wert nach 1.79769e+308 (0x1.fffffffffffffp+1023) ist inf (inf)
löste FE_OVERFLOW aus
löste FE_INEXACT aus
std::nextafter(+0.0, -0.0) ergibt -0.000000
Präzisionsverlust-Demo für float:
nextafter(1e+01, INF) ergibt 10.000001; Δ = 0.000001
nextafter(1e+02, INF) ergibt 100.000008; Δ = 0.000008
nextafter(1e+03, INF) ergibt 1000.000061; Δ = 0.000061
nextafter(1e+04, INF) ergibt 10000.000977; Δ = 0.000977
nextafter(1e+05, INF) ergibt 100000.007812; Δ = 0.007812
nextafter(1e+06, INF) ergibt 1000000.062500; Δ = 0.062500
nextafter(1e+07, INF) ergibt 10000001.000000; Δ = 1.000000
nextafter(1e+08, INF) ergibt 100000008.000000; Δ = 8.000000
Präzisionsverlust-Demo für double:
nextafter(1e+10, INF) ergibt 10000000000.000002; Δ = 0.000002
nextafter(1e+11, INF) ergibt 100000000000.000015; Δ = 0.000015
nextafter(1e+12, INF) ergibt 1000000000000.000122; Δ = 0.000122
nextafter(1e+13, INF) ergibt 10000000000000.001953; Δ = 0.001953
nextafter(1e+14, INF) ergibt 100000000000000.015625; Δ = 0.015625
nextafter(1e+15, INF) ergibt 1000000000000000.125000; Δ = 0.125000
nextafter(1e+16, INF) ergibt 10000000000000002.000000; Δ = 2.000000
Präzisionsverlust-Demo für long double:
nextafter(1e+18, INF) ergibt 1000000000000000000.062500; Δ = 0.062500
nextafter(1e+19, INF) ergibt 10000000000000000001.000000; Δ = 1.000000
nextafter(1e+20, INF) ergibt 100000000000000000008.000000; Δ = 8.000000
Siehe auch
|
C-Dokumentation
für
nextafter
|