namespace std {
float
copysign(float x,
float y); // (1) C++11からC++20まで
double
copysign(double x,
double y); // (2) C++11からC++20まで
long double
copysign(long double x,
long double y); // (3) C++11からC++20まで
constexpr floating-point-type
copysign(floating-point-type x,
floating-point-type y); // (4) C++23
Integral
copysign(Integral x
Integral y); // (5) C++11
constexpr Integral
copysign(Integral x
Integral y); // (5) C++23
float
copysignf(float x,
float y); // (6) C++17
constexpr float
copysignf(float x,
float y); // (6) C++23
long double
copysignl(long double x,
long double y); // (7) C++17
constexpr long double
copysignl(long double x,
long double y); // (7) C++23
}
概要
xの絶対値にyの符号が付いた値を生成する。
- (1) :
floatに対するオーバーロード - (2) :
doubleに対するオーバーロード - (3) :
long doubleに対するオーバーロード - (4) : 浮動小数点数型に対するオーバーロード
- (5) : 整数型に対するオーバーロード (
doubleにキャストして計算される) - (6) :
float型規定 - (7) :
long double型規定
戻り値
xの絶対値にyの符号が付いた値を返す。
xの値がNaNである場合、yの符号が付いたNaNを返す。
備考
- 符号付きゼロを表現するが負のゼロを取り扱わない実装では、この関数はゼロを正と見なす。
- 浮動小数点数の符号ビットを検出したい場合は、
std::signbitを使用できる。NaNの符号を検出できる移植性のある方法はこの2つのみである。 - C++23では、(1), (2), (3)が(4)に統合され、拡張浮動小数点数型を含む浮動小数点数型へのオーバーロードとして定義された
例
#include <iostream>
#include <cmath>
#include <limits>
int main()
{
// 通常の数値
std::cout << "1.0f, 2.0f : " << std::copysign(1.0f, 2.0f) << std::endl;
std::cout << "0.0f, -2.0f : " << std::copysign(0.0f, -2.0f) << std::endl;
std::cout << "1.5f, -0.0f : " << std::copysign(1.5f, -0.0f) << std::endl;
// 無限大
const float inf = std::numeric_limits<float>::infinity();
std::cout << "-inf, 3.0f : " << std::copysign(-inf, 3.0f) << std::endl;
std::cout << "3.0f, -inf : " << std::copysign(3.0f, -inf) << std::endl;
// NaN (Not a Number)
// NaNの符号もコピーされる。
const float nan = std::numeric_limits<float>::quiet_NaN();
std::cout << " nan, -4.2f : " << std::copysign(nan, -4.2f) << std::endl;
std::cout << "4.2f, -nan : " << std::copysign(4.2f, -nan) << std::endl;
}
出力
1.0f, 2.0f : 1
0.0f, -2.0f : -0
1.5f, -0.0f : -1.5
-inf, 3.0f : inf
3.0f, -inf : -3
nan, -4.2f : -nan
4.2f, -nan : -4.2
備考
特定の環境では、早期に constexpr 対応されている場合がある:
- GCC 4.6.1 以上
実装例
namespace std {
float copysign(float x, float y)
{
float absolute_value = std::isnan(x) ?
std::numeric_limits<float>::quiet_NaN() :
std::abs(x);
return y >= 0 ? absolute_value : -absolute_value;
}
double copysign(double x, double y)
{
double absolute_value = std::isnan(x) ?
std::numeric_limits<double>::quiet_NaN() :
std::abs(x);
return y >= 0 ? absolute_value : -absolute_value;
}
long double copysign(long double x, long double y)
{
long double absolute_value = std::isnan(x) ?
std::numeric_limits<long double>::quiet_NaN() :
std::abs(x);
return y >= 0 ? absolute_value : -absolute_value;
}
}
バージョン
言語
- C++11
処理系
- Clang: 3.0 ✅
- GCC: 4.3 ✅
- ICC: ??
- Visual C++: ??
参照
- P0533R9 constexpr for
<cmath>and<cstdlib>- C++23での、一部関数の
constexpr対応
- C++23での、一部関数の
- P1467R9 Extended floating-point types and standard names