Espacios de nombres
Variantes
Acciones

std::nextafter, std::nextafterf, std::nextafterl, std::nexttoward, std::nexttowardf, std::nexttowardl

De cppreference.com
< cpp‎ | numeric‎ | math
 
 
 
Funciones matemáticas comunes
Funciones
Operaciones básicas
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
Funciones exponenciales
(C++11)
(C++11)
(C++11)
(C++11)
Funciones de potencias
(C++11)
(C++11)
Funciones trigonométricas e hiperbólicas
(C++11)
(C++11)
(C++11)
Funciones de error y gamma
(C++11)
(C++11)
(C++11)
(C++11)
Operaciones de punto flotante del entero más cercano
(C++11)(C++11)(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
Funciones de manipulación de punto flotante
(C++11)(C++11)
(C++11)
(C++11)
nextafternexttoward
(C++11)(C++11)
(C++11)
Clasificación/comparación
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Constantes de macro
(C++11)(C++11)(C++11)(C++11)(C++11)
 
Definido en el archivo de encabezado <cmath>
float       nextafter ( float from, float to );
(1) (desde C++11)
(constexpr since C++23)
float       nextafterf( float from, float to );
(2) (desde C++11)
(constexpr since C++23)
double      nextafter ( double from, double to );
(3) (desde C++11)
(constexpr since C++23)
long double nextafter ( long double from, long double to );
(4) (desde C++11)
(constexpr since C++23)
long double nextafterl( long double from, long double to );
(5) (desde C++11)
(constexpr since C++23)
Promovido   nextafter ( Aritmético1 from, Aritmético2 to );
(6) (desde C++11)
(constexpr since C++23)
float       nexttoward ( float from, long double to );
(7) (desde C++11)
(constexpr since C++23)
float       nexttowardf( float from, long double to );
(8) (desde C++11)
(constexpr since C++23)
double      nexttoward ( double from, long double to );
(9) (desde C++11)
(constexpr since C++23)
long double nexttoward ( long double from, long double to );
(10) (desde C++11)
(constexpr since C++23)
long double nexttowardl( long double from, long double to );
(11) (desde C++11)
(constexpr since C++23)
double      nexttoward ( TipoEntero from, long double to );
(12) (desde C++11)
(constexpr since C++23)

Devuelve el siguiente valor representable de from en la dirección de to.

1-5) Si from es igual a to, to.
7-11) Si from es igual a to, se devuelve to, convertida de long double al tipo de retorno de la función sin pérdida de rango o precisión.
6) Un conjunto de sobrecargas o una plantilla de función para todas las combinaciones de los argumentos de tipo aritmético no cubiertas por (1-5). Si algún argumento tiene tipo entero, se convierte en double. Si cualquier argumento es long double, entonces el tipo de retorno Promovido también es long double, de lo contrario, el tipo de retorno siempre es double.
12) Un conjunto de sobrecargas o una plantilla de función que acepta el argumento from de cualquier tipo entero. Equivalente a (9) (el argumento se convierte a double).

Contenido

[editar] Parámetros

from, to - Valores de punto flotante.

[editar] Valor de retorno

Si no se producen errores, se devuelve el siguiente valor representable de from en la dirección de to. Si from es igual a to, entonces to.

Si se produce un error de rango debido a desbordamiento, se devuelve ±HUGE_VAL, ±HUGE_VALF, o ±HUGE_VALL (con el mismo signo que from).

Si se produce un error de rango debido a subdesbordamiento, se devuelve el resultado correcto.

[editar] Manejo de errores

Los errores se informan como se especifica en math_errhandling.

Si la implementación admite la aritmética de punto flotante IEEE (IEC 60559):

  • Si from es finito, pero el resultado esperado es un 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.

[editar] Notas

POSIX especifica que las condiciones de desbordamiento y subdesbordamiento son errores de rango (se puede establecer errno).

IEC 60559 recomienda que se devuelva from siempre que from == to. En su lugar, estas funciones devuelven to, 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.

nextafter generalmente se implementa mediante la manipulación de la representación IEEE (glibc, musl).

[editar] 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 double 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 long double subnormal
    float x = std::nextafter(from1, dir); // primero convierte dir to float, dando 0
    std::cout << "Con nextafter, el próximo float después de " << from1 << " es " << x << '\n';
    x = std::nexttoward(from1, dir);
    std::cout << "Con nexttoward, el próximo 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 << "   generó FE_OVERFLOW\n";
        if(std::fetestexcept(FE_INEXACT)) std::cout << "   generó 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("\nDemo de pérdida de precisión para float:\n", 10.0f);
    precision_loss_demo("\nDemo de pérdida de precisión para double:\n", 10.0e9);
    precision_loss_demo("\nDemo 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 double válidos:
    0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
y   0.1000000000000000055511151231257827021181583404541015625  (0x1.999999999999ap-4)
 
Diferencia entre nextafter y nexttoward:
Con nextafter, el próximo float después de 0 es 0
Con nexttoward, el próximo 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
 
Demo 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
 
Demo 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
 
Demo 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

[editar] Véase también

Documentación de C para nextafter