C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のfesetround()とfegetround()で浮動小数点の丸め方向を制御する方法

この記事では、C++におけるfesetround()fegetround()という2つの関数について詳しく解説します。これらの関数は、標準ライブラリのcfenvヘッダーに含まれており、浮動小数点演算の丸め動作を細かく制御したい場合に非常に便利です。

fesetround()関数とは

fesetround()は、指定した浮動小数点数の丸め方向(丸めモード)を、現在の丸め方向として設定するための関数です。rint()nearbyint()など、C++が提供するさまざまな丸め関数と組み合わせて使用されます。

構文は以下の通りです。

int fesetround(int round);

引数roundには、以下のような丸めモード用マクロを指定できます。

  • FE_TONEAREST:最も近い整数に丸める
  • FE_DOWNWARD:負の無限大方向(切り下げ)へ丸める
  • FE_UPWARD:正の無限大方向(切り上げ)へ丸める
  • FE_TOWARDZERO:ゼロ方向へ丸める(切り捨て)

この関数は、丸め方向の設定が正常に完了した場合に0を返します。

fesetround()の使用例

#include <cfenv>
#include <cmath>
#include <iostream>
using namespace std;

main() {
    double x = 4.7, ans;

    fesetround(FE_TONEAREST); // 最も近い整数に丸める
    ans = rint(x);
    cout << "Nearest Integer is: " << ans << endl;

    fesetround(FE_TOWARDZERO); // ゼロ方向に丸める
    ans = rint(x);
    cout << "Rounding towards 0, value is: " << ans << endl;

    fesetround(FE_DOWNWARD); // 下方向に丸める
    ans = rint(x);
    cout << "Nearest Integer below the number: " << ans << endl;

    fesetround(FE_UPWARD); // 上方向に丸める
    ans = rint(x);
    cout << "Nearest Integer above the number: " << ans << endl;
}

実行結果

Nearest Integer is: 5
Rounding towards 0, value is: 4
Nearest Integer below the number: 4
Nearest Integer above the number: 5

この例では、同じ値4.7に対して、丸めモードを変更することで結果がどのように変化するかを確認できます。FE_TONEARESTでは5に、FE_TOWARDZEROFE_DOWNWARDでは4に、そしてFE_UPWARDでは5に丸められています。

fegetround()関数とは

一方、fegetround()は、現在設定されている丸め方向に対応する丸めマクロを取得するための関数です。こちらもrint()nearbyint()などの丸め関数と併用されることが多く、プログラムの実行中に現在の丸めモードを確認したい場合に役立ちます。

構文は以下の通りです。

int fegetround();

この関数は、現在の丸め方向に対応する次のいずれかのマクロ値を返します。

  • FE_DOWNWARD
  • FE_TONEAREST
  • FE_TOWARDZERO
  • FE_UPWARD

fegetround()の使用例

以下の例では、switch文を使って戻り値を判定し、現在の丸めモード名を出力する補助関数を定義しています。

#include <cfenv>
#include <cmath>
#include <iostream>
using namespace std;

void float_direction() {
    switch (fegetround()) {
        case FE_TONEAREST:
            cout << "Macro is: FE_TONEAREST";
            break;
        case FE_DOWNWARD:
            cout << "Macro is: FE_DOWNWARD";
            break;
        case FE_UPWARD:
            cout << "Macro is: FE_UPWARD";
            break;
        case FE_TOWARDZERO:
            cout << "Macro is: FE_TOWARDZERO";
            break;
        default:
            cout << "unknown";
    };
    cout << endl;
}

main() {
    double x = 4.7, ans;

    fesetround(FE_TONEAREST); // 最も近い整数に丸める
    ans = rint(x);
    cout << "Nearest Integer is: " << ans << endl;
    float_direction();

    fesetround(FE_TOWARDZERO); // ゼロ方向に丸める
    ans = rint(x);
    cout << "Rounding towards 0, value is: " << ans << endl;
    float_direction();

    fesetround(FE_DOWNWARD); // 下方向に丸める
    ans = rint(x);
    cout << "Nearest Integer below the number: " << ans << endl;
    float_direction();

    fesetround(FE_UPWARD); // 上方向に丸める
    ans = rint(x);
    cout << "Nearest Integer above the number: " << ans << endl;
    float_direction();
}

実行結果

Nearest Integer is: 5
Macro is: FE_TONEAREST
Rounding towards 0, value is: 4
Macro is: FE_TOWARDZERO
Nearest Integer below the number: 4
Macro is: FE_DOWNWARD
Nearest Integer above the number: 5
Macro is: FE_UPWARD

このように、fesetround()で丸めモードを変更するたびに、fegetround()がその変更を正しく検出していることがわかります。

まとめ

  • fesetround():丸め方向を設定する関数。成功時は0を返す。
  • fegetround():現在の丸め方向に対応するマクロ値を取得する関数。
  • どちらも<cfenv>ヘッダーで定義され、rint()nearbyint()などの丸め関数の挙動を制御できる。
  • 金額計算や数値シミュレーションなど、丸め方法が重要になる場面で活用できる。
  1. C++のfmax()関数とfmin()関数の使い方を徹底解説

    この記事では、C++におけるfmax()およびfmin()関数の使い方について詳しく解説します。これらの関数は、cmathヘッダーファイルに定義されており、数値比較を簡単に行うための標準ライブラリ関数です。fmax()とfmin()の基本fmax()とfmin()は、それぞれ最大値と最小値を返す関数です。引数として指定できるのは、float、double、long double型の値で、2つの引数を受け取って比較を行います。また、引数の型が異なる場合(例えばfloatとdoubleを比較する場合など)でも、暗黙的に型変換(キャスト)が行われた上で適切な結果が返されるため、異なる浮動小数点型同士

  2. C++のdelete演算子とfree()関数の違いと使い方を徹底解説

    C++やC言語で動的に確保したメモリを解放する方法として、主にdelete演算子とfree()関数の2つがあります。本記事では、それぞれの構文、使い方、そして実際のコード例を通して、両者の違いをわかりやすく解説します。 delete演算子とは delete演算子は、new演算子によって動的に確保されたメモリを解放するために使用されます。プログラマは、この演算子を使って自分で作成したポインタ変数が指すメモリを自由に解放できます。 C++におけるdelete演算子の基本構文は以下の通りです。 delete ポインタ変数名; また、new[]で確保した配列形式のメモリブロックを解放する場合は、次の