3

次のように float のビット パターンを生成しようとすると、次のようになります。

std::cout << std::bitset<32>(32.5) << std::endl;

コンパイラは次の警告を生成します。

warning: implicit conversion from 'double' to 'unsigned long long' changes value
  from 32.5 to 32 [-Wliteral-conversion]
 std::cout << std::bitset<32>(32.5) << std::endl;

警告を無視した場合の出力:):

00000000000000000000000000100000

char* にキャストし、メモリをウォーキングすると正しいシーケンスが表示されるのに、ビットセットがフロートを検出してビット シーケンスを正しく出力できないのはなぜですか? これは機能しますが、バイト順序に依存するマシンであり、ほとんど判読できません:

template <typename T>
  void printMemory(const T& data) {
    const char* begin = reinterpret_cast<const char*>(&data);
    const char* end = begin + sizeof(data);
    while(begin != end)
      std::cout << std::bitset<CHAR_BIT>(*begin++) << " ";
    std::cout << std::endl;
}

出力:

00000000 00000000 00000010 01000010 

フロートをサポートしない理由はありますか? フロートの代替品はありますか?

4

3 に答える 3

3

float を指定した場合、bitset には何が表示されると思いますか? おそらくビッグエンディアン形式のIEEE-7545 binary32浮動小数点数の何らかの表現でしょうか? floatそれに少しでも似たような方法で自分たちを表していないプラットフォームはどうですか? 提供された浮動小数点数を必要なものに変換するために、実装を後方に曲げる必要がありますか?

そうでない理由は、フロートの標準定義形式がないためです。32 ビットである必要さえありません。通常、ほとんどのプラットフォームに存在します。

C++ と C は、非常に小さなプラットフォームや特殊なプラットフォームで実行できます。標準は、「通常のケース」を当てにすることはできません。8/16 ビット 6502 システム用の C/C++ コンパイラがありましたが、ネイティブの浮動小数点形式の言い訳は (私が思うに)パックされた BCD エンコーディングを使用する 6 バイトのエンティティでした。

signedこれは、整数もサポートされていないのと同じ理由です。2 の補数は普遍的ではなく、ほぼ普遍的です。:-)

于 2017-10-20T20:49:38.757 に答える
1
#include <iostream>
#include <bitset>
#include <climits>
#include <iomanip>

using namespace std;

template<class T>
auto toBitset(T x) -> bitset<sizeof(T) * CHAR_BIT>
{
    return bitset<sizeof(T) * CHAR_BIT>{ *reinterpret_cast<unsigned long long int *>(&x) };
}

int main()
{
    double x;
    while (cin >> x) {
        cout << setw(14) << x << " " << toBitset(x) << endl;
    }

    return 0;
}

https://wandbox.org/permlink/tCz5WwHqu2X4CV1E

悲しいことに、引数の型が のサイズよりも大きい場合、これは失敗します。unsigned long longたとえば、 の場合は失敗しlong doubleます。これはbitsetコンストラクタの制限です。

于 2017-10-20T21:34:56.030 に答える