web-dev-qa-db-ja.com

無限大の整数へのキャストは未定義ですか?

無限大(floatで表される)を整数にキャストすることは未定義の動作ですか?

標準は言う:

4.10浮動積分変換

浮動小数点型のprvalueは、整数型のprvalueに変換できます。変換は切り捨てられます。つまり、小数部分は破棄されます。切り捨てられた値を宛先タイプで表すことができない場合、動作は未定義です。

しかし、「切り捨てられた値を表現できない」が無限大をカバーしているかどうかはわかりません。

std::numeric_limits<int>::infinity()static_cast<int>(std::numeric_limits<float>::infinity() )の結果が異なる理由を理解しようとしています。

_#include <iostream>
#include <limits>

int main ()
{
    std::cout << std::numeric_limits<int>::infinity () << std::endl;
    std::cout << static_cast<int> (std::numeric_limits<float>::infinity () ) << std::endl;
    return 0;
}
_

出力:

_0  
-2147483648  
_

std::numeric_limits<int>::infinity()明確に定義されています の結果は_0_と同じですが、無限大のキャストに関する情報が見つかりません。

26
Gluttton

あなたが言った

「切り捨てられた値を表現できない」が無限大をカバーしているかどうかわかりません

しかし、それはすべて要約すると

無限大を切り捨てた結果は何ですか。

C標準(26.9を介してC++に組み込まれている)は、次のように非常にわかりやすく答えています。

C standard semantics for <code>trunc</code>

無限大の切り捨ては依然として無限大であり、無限大はintで表すことができないため(この部分については疑問の余地がないことを願っています)、動作は定義されていません。

16
Ben Voigt

無限大から整数へのキャストは定義されていません。

切り捨てられた値を宛先タイプで表すことができない場合、動作は未定義です。

それをすべて言います。切り捨てによって精度は削除されますが、大きさは削除されないため、切り捨てられた無限大は依然として無限大であり、整数は無限大を表すことはできません。

21
nate

std::numeric_limits<int>::infinity()static_cast<int>(std::numeric_limits<float>::infinity() )の結果が異なる理由を理解しようとしています。

標準によると: 18.3.2.4

static constexpr T infinity()noexcept;

47可能な場合、正の無限大の表現。 [216]

48 has_infinity!= falseであるすべての特殊化に意味があります。 is_iec559!= falseのスペシャライゼーションで必要です。

---編集---

18.3.2.7/1[numeric.special]によると

1すべてのメンバーは、すべての専門分野に提供されるものとします。ただし、多くの値は特定の条件下でのみ意味を持つ必要があります(たとえば、epsilon()はis_integerがfalseの場合にのみ意味があります)。 「意味のある」値ではない値は、0またはfalseに設定する必要があります。

4
kfsone