将Double转换为Hex字符串?

时间:2014-03-26 17:33:36

标签: c++ floating-point hex double

在我的项目中,我将一个双变量读成十六进制并将其加载到一个字符串中。

我需要将该十六进制字符串转换为双数字。我目前使用这个:

double hexstr2double(const std::string& hexstr)
{
    union
    {
        long long i;
        double    d;
    } value;

    value.i = std::stoll(hexstr, nullptr, 16);

    return value.d;
}

当我这样做时:

qDebug() << hexstr2double("402540798D23092A");

输出为10.6259。不确切,但我很好。

然后,用户可以将该编号编辑为他们想要的任何内容。如何将其数字转换回十六进制表示?

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

尽管sstream是一个很好的答案......关于在多线程程序中使用流,有concernshere

与snprintf类似的解决方案:

#include <iostream>
#include <cstdio>

double hexstr2double(const std::string& hexstr)
{
    union
    {
        long long i;
        double    d;
    } value;

    value.i = std::stoll(hexstr, nullptr, 16);

    return value.d;
}

std::string double2hexstr(double x) {

    union
    {
        long long i;
        double    d;
    } value;

   value.d = x;

   char buf[17];

   snprintf (buf,sizeof(buf),"%016llx",value.i);
   buf[16]=0; //make sure it is null terminated.

   return std::string(buf);

}

int main(int argc,char **argv) {
 double a=3.141592;
 std::string x=double2hexstr(a);
 double b=hexstr2double(x);

 std::cout << a << std::endl;
 std::cout << x << std::endl;
 std::cout << b << std::endl;
 return 0;
}

编辑(使用std :: ostringstream的替代版本)

#include <iostream>
#include <sstream>
#include <iomanip>

double hexstr2double(const std::string& hexstr)
{
    union
    {
        long long i;
        double    d;
    } value;

    value.i = std::stoll(hexstr, nullptr, 16);

    return value.d;
}

std::string double2hexstr(double x) {

    union
    {
        long long i;
        double    d;
    } value;

   value.d = x;

   std::ostringstream buf;
   buf << std::hex << std::setfill('0') << std::setw(16) << value.i;

   return buf.str();

}

int main(int argc,char **argv) {
 double a=3.141592;
 std::string x=double2hexstr(a);
 double b=hexstr2double(x);

 std::cout << a << std::endl;
 std::cout << x << std::endl;
 std::cout << b << std::endl;
 return 0;
}

注意......我不是说std​​ :: ostringstream不起作用。它确实具有更好的内存安全属性(因为snprintf具有比sprintf更好的属性)......但是请注意,在多线程程序中(至少在STL的某些实现中)可能会导致过度锁定。

答案 1 :(得分:0)

当您像这样使用union时,请注意它不可移植(不符合C ++标准)。

关于这方面的话题非常多:CppCon 2019: Timur Doumler “Type punning in modern C++”

一致的解决方案可能是:

#include <iostream>
#include <cstdio>
#include <cstdint>
#include <cstring>

double hexstr2double(const std::string& hexstr) {
    uint64_t i = std::stoll(hexstr, nullptr, 16);
    double d;
    std::memcpy(&d,&i,8);
    return d;
}

std::string double2hexstr(double x) {
   uint64_t i;
   std::memcpy(&i,&x,8);

   char buf[17];
   snprintf (buf,sizeof(buf),"%016llx",i);
   buf[16]=0; //make sure it is null terminated.

   return std::string(buf);
}

int main(int argc,char **argv) {
 double a=3.141592;
 std::string x=double2hexstr(a);
 double b=hexstr2double(x);

 std::cout << a << std::endl;
 std::cout << x << std::endl;
 std::cout << b << std::endl;
 return 0;
}