使用union将从double转换为hexadecimal返回double

时间:2017-10-10 14:03:14

标签: c++ operator-overloading

我甚至不确定我的标题是否准确,但对于我的项目,我需要取一个双精度并将其转换为十六进制,然后将其转换为双精度。但为了做到这一点,我想我需要重载运算符<<在我输出答案之前。这是我到目前为止所得到的,但我得到提示“没有操作员”<<“匹配这些操作数”>有人可以指出我应该如何超载<<运营商在主?谢谢!

#include <iostream>
#include <iomanip>
#include <cstdint>

using namespace std;

void out_char_as_hex(int c)
{
    cout << hex << setw(2) << setfill('0') << c;
}


int main()
{
    union { double d; uint64_t u; } tmp;
    double x = -0.15625;
    tmp.d = x;

    cout << out_char_as_hex(tmp.d) << endl;

    return 0;
}

如果它有帮助这就是问题“如果x是double类型的变量,它的二进制表示可以被重新解释为64位整数,可以精确表示。为此,你可以获得内存地址为double类型的变量并重新解释将其强制​​转换为64位int指针或使用union。为了使文本表示更紧凑,我们使用base 16(十六进制)。例如,应保存双数-0.15625以16个字符bfc4000000000000的顺序存档(参见DemoHex.cpp中的示例, 使用工会)。阅读时,需要读取整数 以十六进制格式保存并将其重新解释为double。 您需要修改运算符的实现&lt;&lt;为了双倍 并实现运算符的重载&gt;&gt;“

2 个答案:

答案 0 :(得分:2)

这是一个不使用联合的版本,而是将位模式从double复制到uint64_t

假设此位模式对整数有效,则复制也应该有效。它还产生预期的输出。

#include <iostream>
#include <iomanip>
#include <cstdint>

using namespace std;

void out_char_as_hex(std::uint64_t c)
{
    cout << hex << setw(16) << setfill('0') << c << endl;
}


int main()
{
    uint64_t u;
    double x = -0.15625;

    std::memcpy(&u, &x, sizeof(u));

    out_char_as_hex(u);

    return 0;
}

然而,这不是教授所要求的解决方案,所以可能是“错误的”。

答案 1 :(得分:0)

如果转换只是用于打印,那么您不需要为任何操作员过载。使用io操纵器&#39; std :: hexfloat&#39;你可以用十六进制打印浮点数。

基于您的示例代码和解释,我认为您正在尝试执行以下操作

#include <iostream>
#include <iomanip>

union test
{
    double x;
    uint64_t y;
};

// Insertion operator is overloaded to take union and 
// print uint64_t value from it.  
std::ostream & operator << (std::ostream &out, const test &t)
{
    out << std::hex << std::setw(50) << std::setfill('0') << t.y;
    return out;
}

int main()
{
    test t;
    t.x = -0.15625;
    std::cout << t << std::endl;    
    return 0;
}

这里打印的是用于在内存中存储浮点数的位模式(符号位,指数和尾数)。

更新: 上面的代码会导致未定义的行为,因为我们不是从最近写的成员那里读取的(参考:http://en.cppreference.com/w/cpp/language/union

这是另一种不使用union的方法。

#include <iostream>
#include <iomanip>

struct test
{
    double x;
};

std::ostream & operator << (std::ostream &out, test &t)
{
    uint64_t *y = reinterpret_cast<uint64_t *>(&t.x);
    out << std::hex << std::setw(50) << std::setfill('0') << *y;
    return out;
}

int main()
{
    test t;
    t.x = -0.15625;
    std::cout << t << std::endl;
    return 0;
}