50

floor構文の関数が欲しい

int floor(double x);

しかし、std::floorを返しますdouble。は

static_cast <int> (std::floor(x));

私に正しい整数を与えることが保証されていますか、それともオフバイワンの問題が発生する可能性がありますか? うまくいくようですが、確実に知りたいです。

ボーナス ポイントの場合、一体なぜそもそもa がstd::floor返されるのでしょうか。double

4

5 に答える 5

32

double の範囲は、32 ビットまたは 64 ビット整数の範囲よりもはるかに大きいため、 a がstd::floor返されますdouble。へのキャストintは、それが適切な範囲内にある限り問題ないはずですが、 adoubleはすべての 64 ビット整数を正確に表すことはできないdoubleことに注意してください。連続する 2 つの double の差が 1 より大きいこと。

于 2009-03-03T08:26:42.027 に答える
18
static_cast <int> (std::floor(x));

はい、ほとんどあなたが望むことをします。-infinity に向かって丸められた、最も近い整数が得られます。少なくとも、入力が int で表現できる範囲内にある限り。「.5 などを追加する」とはどういう意味かわかりませんが、同じ効果はありません。

std::floor は double を返します。これが最も一般的なためです。float または double を四捨五入したいが、型を保持したい場合があります。つまり、1.3f を 1 ではなく 1.0f に丸めます。

std::floor が int を返した場合、それは難しいでしょう。(または、少なくとも余分な不要なキャストがあり、速度が低下します)。

floor が型を変更せずに丸めのみを実行する場合は、必要に応じてそれを int にキャストできます。

もう 1 つの理由は、double の範囲が int の範囲よりもはるかに大きいことです。すべての double を int に丸めることができない場合があります。

于 2009-03-03T08:27:07.173 に答える
8

C++ 標準は次のように述べています (4.9.1):

「浮動小数点型の右辺値は、整数型の右辺値に変換できます。変換は切り捨てられます。つまり、小数部分は破棄されます。切り捨てられた値が宛先の型で表現できない場合、動作は未定義です」.

したがって、double を int に変換する場合、数値が int の範囲内にあり、必要な切り上げがゼロに向かっている場合は、単純に数値を int にキャストするだけで十分です。

(int)x;

于 2009-05-26T12:37:49.820 に答える
5

さまざまな数値条件を処理し、さまざまな種類の変換を制御された方法で処理したい場合は、Boost.NumericConversionを確認する必要があります。このライブラリを使用すると、奇妙なケース (範囲外、丸め、範囲など) を処理できます。

ドキュメントの例を次に示します。

#include <cassert>
#include <boost/numeric/conversion/converter.hpp>

int main() {

    typedef boost::numeric::converter<int,double> Double2Int ;

    int x = Double2Int::convert(2.0);
    assert ( x == 2 );

    int y = Double2Int()(3.14); // As a function object.
    assert ( y == 3 ) ; // The default rounding is trunc.

    try
    {
        double m = boost::numeric::bounds<double>::highest();
        int z = Double2Int::convert(m); // By default throws positive_overflow()
    }
    catch ( boost::numeric::positive_overflow const& )
    {
    }

    return 0;
}
于 2009-03-03T08:33:48.200 に答える
2

標準数学ライブラリのほとんどは double を使用しますが、float バージョンも提供します。double を使用したくない場合、std::floorf() は std::floor() の単精度バージョンです。

編集:以前の回答の一部を削除しました。int にキャストする場合、フロアは冗長であると述べましたが、これは正の浮動小数点数にのみ当てはまることを忘れていました。

于 2009-03-03T08:37:53.090 に答える