【问题标题】:Using std::bitset for double representation使用 std::bitset 进行双重表示
【发布时间】:2016-11-22 08:36:07
【问题描述】:

在我的应用程序中,我试图显示双变量的位表示。 它适用于较小的双变量。不适用于 10^30 级别。

代码:

#include <iostream>
#include <bitset>
#include <limits>
#include <string.h>

using namespace std;

void Display(double doubleValue)
{
    bitset<sizeof(double) * 8> b(doubleValue);
    cout << "Value  : " << doubleValue << endl;
    cout << "BitSet : " << b.to_string() << endl;
}

int main()
{
    Display(1000000000.0);
    Display(2000000000.0);
    Display(3000000000.0);

    Display(1000000000000000000000000000000.0);
    Display(2000000000000000000000000000000.0);
    Display(3000000000000000000000000000000.0);

    return 0;   
}

输出:

/home/sujith% ./a.out
Value  : 1e+09
BitSet : 0000000000000000000000000000000000111011100110101100101000000000
Value  : 2e+09
BitSet : 0000000000000000000000000000000001110111001101011001010000000000
Value  : 3e+09
BitSet : 0000000000000000000000000000000010110010110100000101111000000000
Value  : 1e+30
BitSet : 0000000000000000000000000000000000000000000000000000000000000000
Value  : 2e+30
BitSet : 0000000000000000000000000000000000000000000000000000000000000000
Value  : 3e+30
BitSet : 0000000000000000000000000000000000000000000000000000000000000000

我担心为什么 bitset 总是给出 64,后面的 3 为零。有趣的是,实际值的“cout”按预期工作。

【问题讨论】:

    标签: c++ double bitset


    【解决方案1】:

    如果您查看the std::bitset constructor,您会发现它要么接受字符串作为参数,要么接受整数。

    这意味着您的double 值将被转换为整数,并且没有标准的整数类型可以容纳如此大的值,这会导致未定义的行为。

    如果你想得到double 的实际位,你需要做一些转换技巧来使它工作:

    unsigned long long bits = *reinterpret_cast<unsigned long long*>(&doubleValue);
    

    注意像这样的type-punning在C++规范中没有定义,但是只要sizeof(double) == sizeof(unsigned long long)就可以了。如果您希望行为得到明确定义,则必须遍历 char 和 char* 的数组。

    【讨论】:

    • 在这种情况下,类型双关的替代方法可能是旧的std::memcpy。
    • 您需要使用 C++14 为 std::bitset 获取 unsigned long long 构造函数。
    【解决方案2】:

    使用 C++14,std::bitset 现在采用 unsigned long long 构造函数,所以这可能会起作用:

    union udouble {
      double d;
      unsigned long long u;
    };
    
    void Display(double doubleValue)
    {
        udouble ud;
        ud.d = doubleValue;
        bitset<sizeof(double) * 8> b(ud.u);
        cout << "Value  : " << doubleValue << endl;
        cout << "BitSet : " << b.to_string() << endl;
    }
    

    这应该为您提供双精度的内部表示。请参阅IdeOne 上的工作示例代码。

    【讨论】:

    • 不幸的是,使用联合的类型双关语在 C++ 中未定义。它应该可以工作。
    猜你喜欢
    • 2014-10-13
    • 1970-01-01
    • 2023-03-03
    • 2019-10-24
    • 2011-07-12
    • 2013-06-25
    • 2020-01-13
    • 1970-01-01
    相关资源
    最近更新 更多