Namespaces
Variants

std:: remquo, std:: remquof, std:: remquol

From 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)
Classification and comparison
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Types
(C++11)
(C++11)
(C++11)
Macro constants
헤더에 정의됨 <cmath>
(1)
float remquo ( float x, float y, int * quo ) ;

double remquo ( double x, double y, int * quo ) ;

long double remquo ( long double x, long double y, int * quo ) ;
(C++11 이후)
(C++23 이전)
constexpr /* floating-point-type */

remquo ( /* floating-point-type */ x,

/* floating-point-type */ y, int * quo ) ;
(C++23 이후)
float remquof ( float x, float y, int * quo ) ;
(2) (C++11 이후)
(C++23부터 constexpr)
long double remquol ( long double x, long double y, int * quo ) ;
(3) (C++11 이후)
(C++23부터 constexpr)
헤더에 정의됨 <cmath>
template < class Arithmetic1, class Arithmetic2 >

/* common-floating-point-type */

remquo ( Arithmetic1 x, Arithmetic2 y, int * quo ) ;
(A) (C++11 이후)
(C++23부터 constexpr)
1-3) x / y 나눗셈 연산의 부동소수점 나머지를 std::remainder() 함수와 동일하게 계산합니다. 추가적으로, x / y 의 부호와 최소한 마지막 3비트 정보가 quo 에 저장되어, 주기 내에서 결과의 옥탄트(octant)를 결정하는 데 충분합니다. 라이브러리는 모든 cv-한정되지 않은 부동소수점 타입에 대한 std::remquo 의 오버로드를 매개변수 x y 의 타입으로 제공합니다. (C++23부터)
A) 추가적인 오버로드들이 다른 모든 산술 타입 조합에 대해 제공됩니다.

목차

매개변수

x, y - 부동 소수점 또는 정수 값
quo - int 를 가리키는 포인터로, x / y 의 부호와 일부 비트를 저장함

반환값

성공 시, std::remainder 에 정의된 대로 x / y 나눗셈의 부동소수점 나머지를 반환하고, * quo 에는 x / y 의 부호와 최소 세 개의 최하위 비트를 저장합니다 (공식적으로, 부호가 x / y 의 부호와 같고 크기가 2 n
모듈로 x / y 의 정수 몫 크기와 합동인 값을 저장하며, 여기서 n 은 구현에서 정의된 3 이상의 정수입니다).

만약 y 가 0이면, * quo 에 저장되는 값은 지정되지 않습니다.

도메인 오류가 발생하면 구현에서 정의한 값이 반환됩니다(NaN이 지원되는 경우).

언더플로우로 인해 범위 오류가 발생하는 경우, 서브노멀을 지원하면 올바른 결과가 반환됩니다.

만약 y 가 0이지만 도메인 오류가 발생하지 않는 경우, 0이 반환됩니다.

오류 처리

오류는 math_errhandling 에 명시된 대로 보고됩니다.

y 가 0인 경우 도메인 오류가 발생할 수 있습니다.

구현이 IEEE 부동 소수점 연산(IEC 60559)을 지원하는 경우,

  • 현재 반올림 모드 는 영향을 미치지 않습니다.
  • FE_INEXACT 는 절대 발생하지 않습니다.
  • 만약 x 가 ±∞이고 y 가 NaN이 아니면, NaN이 반환되고 FE_INVALID 가 발생합니다.
  • 만약 y 가 ±0이고 x 가 NaN이 아니면, NaN이 반환되고 FE_INVALID 가 발생합니다.
  • 만약 x 또는 y 가 NaN이면, NaN이 반환됩니다.

참고 사항

POSIX는 x 가 무한대이거나 y 가 0인 경우 도메인 오류가 발생하도록 요구합니다.

이 함수는 주기가 부동 소수점 값으로 정확히 표현될 수 있는 주기 함수를 구현할 때 유용합니다: 매우 큰 x 에 대해 sin(πx) 를 계산할 때, std::sin 을 직접 호출하면 큰 오차가 발생할 수 있지만, 함수 인수를 먼저 std::remquo 로 환산하면, 몫의 하위 비트들을 사용하여 주기 내 결과의 부호와 팔분위를 결정하는 동시에 나머지를 사용하여 높은 정밀도로 값을 계산할 수 있습니다.

일부 플랫폼에서는 이 연산이 하드웨어에서 지원됩니다 (예를 들어, Intel CPU에서는 FPREM1 이 완료될 때 몫에 정확히 3비트의 정밀도를 남깁니다).

추가 오버로드는 반드시 (A) 와 정확히 동일하게 제공될 필요는 없습니다. 이들은 단지 첫 번째 인수 num1 와 두 번째 인수 num2 에 대해 다음을 보장할 수 있을 만큼 충분하기만 하면 됩니다:

  • num1 또는 num2 long double 타입을 가지는 경우, std :: remquo ( num1, num2, quo ) 는 다음 코드와 동일한 효과를 가집니다: std :: remquo ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) , quo )
    .
  • 그렇지 않고 num1 및/또는 num2 double 또는 정수 타입을 가지는 경우, std :: remquo ( num1, num2, quo ) 는 다음 코드와 동일한 효과를 가집니다: std :: remquo ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) , quo )
    .
  • 그렇지 않고 num1 또는 num2 float 타입을 가지는 경우, std :: remquo ( num1, num2, quo ) 는 다음 코드와 동일한 효과를 가집니다: std :: remquo ( static_cast < float > ( num1 ) ,
    static_cast < float > ( num2 ) , quo )
    .
(C++23 이전)

num1 num2 이 산술 타입을 가지는 경우, std :: remquo ( num1, num2, quo ) 는 다음 코드와 동일한 효과를 가집니다: std :: remquo ( static_cast < /*common-floating-point-type*/ > ( num1 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) , quo )
, 여기서 /*common-floating-point-type*/ num1 num2 의 타입들 사이에서 가장 높은 부동소수점 변환 순위 와 가장 높은 부동소수점 변환 하위 순위 를 가지는 부동소수점 타입이며, 정수 타입 인수들은 double 과 동일한 부동소수점 변환 순위를 가진 것으로 간주됩니다.

가장 높은 순위와 하위 순위를 가지는 부동소수점 타입이 존재하지 않는 경우, 오버로드 해결 은 제공된 오버로드들 중에서 사용 가능한 후보를 결과로 내지 않습니다.

(C++23 이후)

예제

#include <cfenv>
#include <cmath>
#include <iostream>
#ifndef __GNUC__
#pragma STDC FENV_ACCESS ON
#endif
const double pi = std::acos(-1); // 또는 C++20부터는 std::numbers::pi
double cos_pi_x_naive(double x)
{
    return std::cos(pi * x);
}
// 주기는 2이며, 값들은 (0;0.5) 양수, (0.5;1.5) 음수, (1.5,2) 양수
double cos_pi_x_smart(double x)
{
    int quadrant;
    double rem = std::remquo(x, 1, &quadrant);
    quadrant = static_cast<unsigned>(quadrant) % 2; // 주기는 2입니다.
    return quadrant == 0 ?  std::cos(pi * rem)
                         : -std::cos(pi * rem);
}
int main()
{
    std::cout << std::showpos
              << "naive:\n"
              << "  cos(pi * 0.25) = " << cos_pi_x_naive(0.25) << '\n'
              << "  cos(pi * 1.25) = " << cos_pi_x_naive(1.25) << '\n'
              << "  cos(pi * 2.25) = " << cos_pi_x_naive(2.25) << '\n'
              << "smart:\n"
              << "  cos(pi * 0.25) = " << cos_pi_x_smart(0.25) << '\n'
              << "  cos(pi * 1.25) = " << cos_pi_x_smart(1.25) << '\n'
              << "  cos(pi * 2.25) = " << cos_pi_x_smart(2.25) << '\n'
              << "naive:\n"
              << "  cos(pi * 1000000000000.25) = "
              << cos_pi_x_naive(1000000000000.25) << '\n'
              << "  cos(pi * 1000000000001.25) = "
              << cos_pi_x_naive(1000000000001.25) << '\n'
              << "smart:\n"
              << "  cos(pi * 1000000000000.25) = "
              << cos_pi_x_smart(1000000000000.25) << '\n'
              << "  cos(pi * 1000000000001.25) = "
              << cos_pi_x_smart(1000000000001.25) << '\n';
    // 오류 처리
    std::feclearexcept(FE_ALL_EXCEPT);
    int quo;
    std::cout << "remquo(+Inf, 1) = " << std::remquo(INFINITY, 1, &quo) << '\n';
    if (fetestexcept(FE_INVALID))
        std::cout << "  FE_INVALID raised\n";
}

가능한 출력:

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

참고 항목

정수 나눗셈의 몫과 나머지를 계산합니다
(함수)
(C++11) (C++11)
부동 소수점 나눗셈 연산의 나머지
(함수)
(C++11) (C++11) (C++11)
부호 있는 나눗셈 연산의 나머지
(함수)
C 문서 for remquo