Namespaces
Variants

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

From es.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)
nextafter nexttoward
(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
Definido en el encabezado <cmath>
(1)
float nextafter ( float from, float to ) ;

double nextafter ( double from, double to ) ;

long double nextafter ( long double from, long double to ) ;
(desde C++11)
(hasta C++23)
constexpr /* floating-point-type */

nextafter ( /* floating-point-type */ from,

/* floating-point-type */ to ) ;
(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 ) ;

long double nexttoward ( long double from, long double to ) ;
(desde C++11)
(hasta C++23)
constexpr /* floating-point-type */

nexttoward ( /* floating-point-type */ from,

long double to ) ;
(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 */

nextafter ( Arithmetic1 from, Arithmetic2 to ) ;
(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 .

1-3) Si from es igual a to , to es retornado. La biblioteca proporciona sobrecargas de 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)
4-6) Si from es igual a to , to es retornado, convertido de long double al tipo de retorno de la función sin pérdida de rango o precisión.

La biblioteca proporciona sobrecargas de std::nexttoward para todos los tipos de punto flotante sin calificación cv como el tipo del parámetro from . Sin embargo, una invocación de std::nexttoward está mal formada si el argumento correspondiente a from tiene tipo de punto flotante extendido , porque el siguiente valor representable (o to ) no está garantizado que sea representable como long double .

(desde C++23)
A) Se proporcionan sobrecargas adicionales de std::nextafter para todas las demás combinaciones de tipos aritméticos.
B) Se proporcionan sobrecargas adicionales de 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 :

  • Si num1 o num2 tiene tipo long double , entonces std :: nextafter ( num1, num2 ) tiene el mismo efecto que std :: nextafter ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) )
    .
  • En caso contrario, si num1 y/o num2 tiene tipo double o un tipo entero, entonces std :: nextafter ( num1, num2 ) tiene el mismo efecto que std :: nextafter ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) )
    .
  • En caso contrario, si num1 o num2 tiene tipo float , entonces std :: nextafter ( num1, num2 ) tiene el mismo efecto que std :: nextafter ( static_cast < float > ( num1 ) ,
    static_cast < float > ( 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 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) )
, donde /*common-floating-point-type*/ es el tipo de punto flotante con el mayor rango de conversión de punto flotante y mayor subrango de conversión de punto flotante entre los tipos de num1 y num2 , los argumentos de tipo entero se consideran con el mismo rango de conversión de punto flotante que double .

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