Namespaces
Variants

remquo, remquof, remquol

From cppreference.net
< c ‎ | numeric ‎ | math
Common mathematical functions
Functions
Basic operations
remquo
(C99)
(C99)
(C99)
(C99) (C99) (C99) (C23)
Maximum/minimum operations
Exponential functions
Power functions
Trigonometric and hyperbolic functions
Nearest integer floating-point
(C99) (C99) (C99)
(C23) (C23) (C23) (C23)
Floating-point manipulation
Narrowing operations
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
Quantum and quantum exponent
Decimal re-encoding functions
Total order and payload functions
Classification
Error and gamma functions
(C99)
(C99)
(C99)
(C99)
Types
Macro constants
Special floating-point values
Arguments and return values
Error handling
Fast operation indicators
Definido en el encabezado <math.h>
float remquof ( float x, float y, int * quo ) ;
(1) (desde C99)
double remquo ( double x, double y, int * quo ) ;
(2) (desde C99)
long double remquol ( long double x, long double y, int * quo ) ;
(3) (desde C99)
Definido en el encabezado <tgmath.h>
#define remquo( x, y, quo )
(4) (desde C99)
1-3) Calcula el resto en punto flotante de la operación de división x / y como lo hace la función remainder() . Adicionalmente, el signo y al menos tres de los últimos bits de x / y se almacenarán en quo , suficiente para determinar el octante del resultado dentro de un período.
4) Macro genérica de tipos: Si cualquier argumento no puntero tiene tipo long double , remquol es llamado. De lo contrario, si cualquier argumento no puntero tiene tipo entero o tiene tipo double , remquo es llamado. De lo contrario, remquof es llamado.

Contenidos

Parámetros

x, y - valores de punto flotante
quo - puntero a un valor entero para almacenar el signo y algunos bits de x / y

Valor de retorno

Si tiene éxito, retorna el resto en punto flotante de la división x / y como se define en remainder , y almacena, en * quo , el signo y al menos tres de los bits menos significativos de x / y (formalmente, almacena un valor cuyo signo es el signo de x / y y cuya magnitud es congruente módulo 2 n
con la magnitud del cociente integral de x / y , donde n es un entero definido por la implementación mayor o igual a 3 ).

Si y es cero, el valor almacenado en * quo no está especificado.

Si ocurre un error de dominio, se devuelve un valor definido por la implementación (NaN donde esté soportado).

Si ocurre un error de rango debido a desbordamiento inferior, se devuelve el resultado correcto si se admiten subnormales.

Si y es cero, pero no se produce el error de dominio, se devuelve cero.

Manejo de errores

Los errores se reportan como se especifica en math_errhandling .

Puede ocurrir un error de dominio si y es cero.

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

  • El modo de redondeo actual rounding mode no tiene efecto.
  • FE_INEXACT nunca se activa
  • Si x es ±∞ y y no es NaN, se retorna NaN y FE_INVALID se activa
  • Si y es ±0 y x no es NaN, se retorna NaN y FE_INVALID se activa
  • Si cualquiera x o y es NaN, se retorna NaN

Notas

POSIX requiere que ocurra un error de dominio si x es infinito o y es cero.

Esta función es útil al implementar funciones periódicas con el período exactamente representable como un valor de punto flotante: al calcular sin(πx) para un x muy grande, llamar a sin directamente puede resultar en un gran error, pero si el argumento de la función se reduce primero con remquo , los bits de menor orden del cociente pueden usarse para determinar el signo y el octante del resultado dentro del período, mientras que el resto puede usarse para calcular el valor con alta precisión.

En algunas plataformas esta operación es soportada por hardware (y, por ejemplo, en CPU Intel, FPREM1 deja exactamente 3 bits de precisión en el cociente).

Ejemplo

#include <fenv.h>
#include <math.h>
#include <stdio.h>
#ifndef __GNUC__
#pragma STDC FENV_ACCESS ON
#endif
double cos_pi_x_naive(double x)
{
    const double pi = acos(-1);
    return cos(pi * x);
}
// el período es 2, los valores son (0;0.5) positivos, (0.5;1.5) negativos, (1.5,2) positivos
double cos_pi_x_smart(double x)
{
    const double pi = acos(-1);
    int extremum;
    double rem = remquo(x, 1, &extremum);
    extremum = (unsigned)extremum % 2; // mantener 1 bit para determinar el extremo más cercano
    return extremum ? -cos(pi * rem) : cos(pi * rem);
}
int main(void)
{
    printf("cos(pi * 0.25) = %f\n", cos_pi_x_naive(0.25));
    printf("cos(pi * 1.25) = %f\n", cos_pi_x_naive(1.25));
    printf("cos(pi * 1000000000000.25) = %f\n", cos_pi_x_naive(1000000000000.25));
    printf("cos(pi * 1000000000001.25) = %f\n", cos_pi_x_naive(1000000000001.25));
    printf("cos(pi * 1000000000000.25) = %f\n", cos_pi_x_smart(1000000000000.25));
    printf("cos(pi * 1000000000001.25) = %f\n", cos_pi_x_smart(1000000000001.25));
    // manejo de errores
    feclearexcept(FE_ALL_EXCEPT);
    int quo;
    printf("remquo(+Inf, 1) = %.1f\n", remquo(INFINITY, 1, &quo));
    if (fetestexcept(FE_INVALID))
        puts("    FE_INVALID raised");
}

Salida posible:

cos(pi * 0.25) = 0.707107
cos(pi * 1.25) = -0.707107
cos(pi * 1000000000000.25) = 0.707123
cos(pi * 1000000000001.25) = -0.707117
cos(pi * 1000000000000.25) = 0.707107
cos(pi * 1000000000001.25) = -0.707107 
remquo(+Inf, 1) = -nan
    FE_INVALID raised

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 7.12.10.3 Las funciones remquo (p: TBD)
  • 7.25 Matemáticas genéricas de tipos <tgmath.h> (p: TBD)
  • F.10.7.3 Las funciones remquo (p: TBD)
  • Estándar C17 (ISO/IEC 9899:2018):
  • 7.12.10.3 Las funciones remquo (p: 186)
  • 7.25 Matemáticas genéricas de tipos <tgmath.h> (p: 272-273)
  • F.10.7.3 Las funciones remquo (p: 385)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 7.12.10.3 Las funciones remquo (p: 255)
  • 7.25 Matemáticas genéricas de tipo <tgmath.h> (p: 373-375)
  • F.10.7.3 Las funciones remquo (p: 529)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 7.12.10.3 Las funciones remquo (p: 236)
  • 7.22 Matemáticas genéricas de tipo <tgmath.h> (p: 335-337)
  • F.9.7.3 Las funciones remquo (p: 465)

Véase también

calcula el cociente y el resto de la división entera
(función)
(C99) (C99)
calcula el resto de la operación de división de punto flotante
(función)
calcula el resto con signo de la operación de división de punto flotante
(función)