最終更新日時(UTC):
が更新

履歴 編集

function
<cmath>

std::copysign(C++11)

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の符号が付いた値を生成する。

戻り値

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

処理系

参照