std:: nextafter, std:: nextafterf, std:: nextafterl, std:: nexttoward, std:: nexttowardf, std:: nexttowardl
|
Definido en el encabezado
<cmath>
|
||
| (1) | ||
|
float
nextafter
(
float
from,
float
to
)
;
double
nextafter
(
double
from,
double
to
)
;
|
(desde C++11)
(hasta C++23) |
|
|
constexpr
/* floating-point-type */
nextafter
(
/* floating-point-type */
from,
|
(desde C++23) | |
|
float
nextafterf
(
float
from,
float
to
)
;
|
(2) |
(desde C++11)
(constexpr desde C++23) |
|
long
double
nextafterl
(
long
double
from,
long
double
to
)
;
|
(3) |
(desde C++11)
(constexpr desde C++23) |
| (4) | ||
|
float
nexttoward
(
float
from,
long
double
to
)
;
double
nexttoward
(
double
from,
long
double
to
)
;
|
(desde C++11)
(hasta C++23) |
|
|
constexpr
/* floating-point-type */
nexttoward
(
/* floating-point-type */
from,
|
(desde C++23) | |
|
float
nexttowardf
(
float
from,
long
double
to
)
;
|
(5) |
(desde C++11)
(constexpr desde C++23) |
|
long
double
nexttowardl
(
long
double
from,
long
double
to
)
;
|
(6) |
(desde C++11)
(constexpr desde C++23) |
|
Definido en el encabezado
<cmath>
|
||
|
template
<
class
Arithmetic1,
class
Arithmetic2
>
/* common-floating-point-type */
|
(A) |
(desde C++11)
(constexpr desde C++23) |
|
template
<
class
Integer
>
double nexttoward ( Integer from, long double to ) ; |
(B) |
(desde C++11)
(constexpr desde C++23) |
Devuelve el siguiente valor representable de from en la dirección de to .
std::nextafter
para todos los tipos de punto flotante sin calificación cv como el tipo de los parámetros
from
y
to
.
(desde C++23)
|
La biblioteca proporciona sobrecargas de
|
(desde C++23) |
std::nextafter
para todas las demás combinaciones de tipos aritméticos.
std::nexttoward
para todos los tipos enteros, los cuales son tratados como
double
.
Contenidos |
Parámetros
| desde, hasta | - | valores de punto flotante o enteros |
Valor de retorno
Si no ocurren errores, se devuelve el siguiente valor representable de from en la dirección de to . Si from es igual a to , entonces se devuelve to .
Si ocurre un error de rango debido a desbordamiento,
±HUGE_VAL
,
±HUGE_VALF
, o
±HUGE_VALL
es devuelto (con el mismo signo que
from
).
Si ocurre un error de rango debido a subdesbordamiento, se devuelve el resultado correcto.
Manejo de errores
Los errores se reportan como se especifica en math_errhandling .
Si la implementación soporta aritmética de punto flotante IEEE (IEC 60559),
- si from es finito, pero el resultado esperado es infinito, genera FE_INEXACT y FE_OVERFLOW .
- si from no es igual a to y el resultado es subnormal o cero, genera FE_INEXACT y FE_UNDERFLOW .
- en cualquier caso, el valor devuelto es independiente del modo de redondeo actual.
- si from o to es NaN, se devuelve NaN.
Notas
POSIX especifica que las condiciones de desbordamiento y subdesbordamiento son errores de rango ( errno puede establecerse).
IEC 60559 recomienda que from sea devuelto cuando from == to . Estas funciones devuelven to en su lugar, lo que hace que el comportamiento alrededor de cero sea consistente: std :: nextafter ( - 0.0 , + 0.0 ) devuelve + 0.0 y std :: nextafter ( + 0.0 , - 0.0 ) devuelve - 0.0 .
std::nextafter
normalmente se implementa mediante manipulación de la representación IEEE (
glibc
,
musl
).
Las sobrecargas adicionales de
std::nextafter
no están obligadas a proporcionarse exactamente como
(A)
. Solo necesitan ser suficientes para garantizar que para su primer argumento
num1
y segundo argumento
num2
:
|
(hasta C++23) |
|
Si
num1
y
num2
tienen tipos aritméticos, entonces
std
::
nextafter
(
num1, num2
)
tiene el mismo efecto que
std
::
nextafter
(
static_cast
<
/*common-floating-point-type*/
>
(
num1
)
,
Si no existe tal tipo de punto flotante con el mayor rango y subrango, entonces la resolución de sobrecarga no resulta en un candidato utilizable de las sobrecargas proporcionadas. |
(desde C++23) |
Las sobrecargas adicionales de
std::nexttoward
no están obligadas a proporcionarse exactamente como
(B)
. Solo necesitan ser suficientes para garantizar que para su argumento
num
de tipo entero,
std
::
nexttoward
(
num
)
tenga el mismo efecto que
std
::
nexttoward
(
static_cast
<
double
>
(
num
)
)
.
Ejemplo
#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 << "El siguiente float representable después de " << std::setprecision(20) << from1 << " es " << to1 << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat; float from2 = 1, to2 = std::nextafter(from2, 2.f); std::cout << "El siguiente float representable después de " << from2 << " es " << to2 << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat; double from3 = std::nextafter(0.1, 0), to3 = 0.1; std::cout << "El número 0.1 se encuentra entre dos doubles válidos:\n" << std::setprecision(56) << " " << from3 << std::hexfloat << " (" << from3 << ')' << std::defaultfloat << "\ny " << to3 << std::hexfloat << " (" << to3 << ")\n" << std::defaultfloat << std::setprecision(20); std::cout << "\nDiferencia entre nextafter y nexttoward:\n"; long double dir = std::nextafter(from1, 1.0L); // primer subnormal long double float x = std::nextafter(from1, dir); // primero convierte dir a float, dando 0 std::cout << "Con nextafter, el siguiente float después de " << from1 << " es " << x << '\n'; x = std::nexttoward(from1, dir); std::cout << "Con nexttoward, el siguiente float después de " << from1 << " es " << x << '\n'; std::cout << "\nValores especiales:\n"; { // #pragma STDC FENV_ACCESS ON std::feclearexcept(FE_ALL_EXCEPT); double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY); std::cout << "El siguiente double representable después de " << std::setprecision(6) << from4 << std::hexfloat << " (" << from4 << ')' << std::defaultfloat << " es " << to4 << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat; if (std::fetestexcept(FE_OVERFLOW)) std::cout << " lanzó FE_OVERFLOW\n"; if (std::fetestexcept(FE_INEXACT)) std::cout << " lanzó FE_INEXACT\n"; } // fin del bloque FENV_ACCESS float from5 = 0.0, to5 = std::nextafter(from5, -0.0); std::cout << "std::nextafter(+0.0, -0.0) da " << 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) da " << std::fixed << std::setprecision(6) << to << "; Δ = " << Δ << '\n'; }; precision_loss_demo("\nDemostración de pérdida de precisión para float:\n", 10.0f); precision_loss_demo("\nDemostración de pérdida de precisión para double:\n", 10.0e9); precision_loss_demo("\nDemostración de pérdida de precisión para long double:\n", 10.0e17L); }
Salida:
El siguiente float representable después de 0 es 1.4012984643248170709e-45 (0x1p-149)
El siguiente float representable después de 1 es 1.0000001192092895508 (0x1.000002p+0)
El número 0.1 se encuentra entre dos doubles válidos:
0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
y 0.1000000000000000055511151231257827021181583404541015625 (0x1.999999999999ap-4)
Diferencia entre nextafter y nexttoward:
Con nextafter, el siguiente float después de 0 es 0
Con nexttoward, el siguiente float después de 0 es 1.4012984643248170709e-45
Valores especiales:
El siguiente double representable después de 1.79769e+308 (0x1.fffffffffffffp+1023) es inf (inf)
generó FE_OVERFLOW
generó FE_INEXACT
std::nextafter(+0.0, -0.0) da -0.000000
Demostración de pérdida de precisión para float:
nextafter(1e+01, INF) da 10.000001; Δ = 0.000001
nextafter(1e+02, INF) da 100.000008; Δ = 0.000008
nextafter(1e+03, INF) da 1000.000061; Δ = 0.000061
nextafter(1e+04, INF) da 10000.000977; Δ = 0.000977
nextafter(1e+05, INF) da 100000.007812; Δ = 0.007812
nextafter(1e+06, INF) da 1000000.062500; Δ = 0.062500
nextafter(1e+07, INF) da 10000001.000000; Δ = 1.000000
nextafter(1e+08, INF) da 100000008.000000; Δ = 8.000000
Demostración de pérdida de precisión para double:
nextafter(1e+10, INF) da 10000000000.000002; Δ = 0.000002
nextafter(1e+11, INF) da 100000000000.000015; Δ = 0.000015
nextafter(1e+12, INF) da 1000000000000.000122; Δ = 0.000122
nextafter(1e+13, INF) da 10000000000000.001953; Δ = 0.001953
nextafter(1e+14, INF) da 100000000000000.015625; Δ = 0.015625
nextafter(1e+15, INF) da 1000000000000000.125000; Δ = 0.125000
nextafter(1e+16, INF) da 10000000000000002.000000; Δ = 2.000000
Demostración de pérdida de precisión para long double:
nextafter(1e+18, INF) da 1000000000000000000.062500; Δ = 0.062500
nextafter(1e+19, INF) da 10000000000000000001.000000; Δ = 1.000000
nextafter(1e+20, INF) da 100000000000000000008.000000; Δ = 8.000000
Véase también
|
Documentación de C
para
nextafter
|