double to hex string & hex string to double

26,101

Solution 1

I am surprised to see nobody has come up with the standard solution, which is the %a format specifier in the ISO C99 Standard.

#include <iostream>
#include <string>
#include <stdio.h>

std::string double2hexastr(double d) {

  char buffer[25] = { 0 };

  ::snprintf(buffer, 25, "%A", d); // TODO Check for errors

  return buffer;
}

double hexastr2double(const std::string& s) {

  double d = 0.0;

  ::sscanf(s.c_str(), "%lA", &d); // TODO Check for errors

  return d;
}


int main() {

  std::cout << "0.1 in hexadecimal: " << double2hexastr(0.1) << std::endl;

  std::cout << "Reading back 0X1.999999999999AP-4, it is ";

  std::cout << hexastr2double("0X1.999999999999AP-4") << std::endl;

}

Solution 2

char *doubleToRawString(double x) {
    // Assumes sizeof(long long) == 8.

    char *buffer = new char[32];
    sprintf(buffer, "%llx", *(unsigned long long *)&x);  // Evil!
    return buffer;
}

double rawStringToDouble(const char *s) {
    // Assumes sizeof(long long) == 8.

    double ret;
    sscanf(s, "%llx", (unsigned long long *)&ret);  // Evil!
    return ret;
}

Solution 3

char *doubleToRawString(double x) {
    const size_t bytesInDouble = 8;

    union {
        double value;
        unsigned char bytes[bytesInDouble];
    } u;

    u.value = x;

    char *buffer = new char[bytesInDouble * 2 + 1];
    unsigned char *input = u.bytes;
    char *output = buffer;

    for(int i = 0; i < bytesInDouble; ++i) {
        sprintf(output, "%02hhX", *input);

        ++input;
        output += 2;
    }

    return buffer;
}

double rawStringToDouble(const char *input) {
    const size_t bytesInDouble = 8;

    union {
        double value;
        unsigned char bytes[bytesInDouble];
    } u;

    unsigned char *output = u.bytes;

    for(int i = 0; i < bytesInDouble; ++i) {
        sscanf(input, "%02hhX", output);

        input += 2;
        ++output;
    }

    return u.value;
}

This uses the non-standard hh modifier. If you don't want to use that, use:

unsigned int tmp = *input;
sprintf(output, "%02X", tmp);

unsigned int tmp;
sscanf(input, "%02X", &tmp);
*output = tmp;

Solution 4

For MFC, convert double to CString :)

CString MFCClass::DoubleToCString(double d, int beforKomma)
{
    char a[17]="0123456789ABCDEF";
    CString str = _T("");
    double dInt=0,dPunkt=0;
    bool is_otr=0;
    if (d<0) {is_otr=1; d=-d;}
    dPunkt = modf(d, &dInt);
    //целая часть
    long ld = (long)dInt;
    long mask = 0xf;
    int it;
    while(ld>0)
    {
        it = ld&mask;
        ld = ld>>4;
        str.Insert(0,a[it]);
    };
    // дробная часть
    //если целая часть 0:
    if (str.GetLength()==0) str += _T("0");
    str += _T(".");
    for (int i=0; i<beforKomma; i++)
    {
        dPunkt*=16;
        dPunkt = modf(dPunkt, &dInt);
        str += a[(int)dInt];
    }

    if (is_otr) str.Insert(0,_T("-"));
    return (str);
}

-345.86783907228863 -> "-159.DE2" (beforKomma=3)

Share:
26,101
Admin
Author by

Admin

Updated on August 22, 2020

Comments

  • Admin
    Admin over 3 years

    What I'm trying to do is to convert a double to hex string and then back to double.

    The following code does conversion double-to-hex string.

    char * double2HexString(double a)
    {
       char *buf = new char[17]; // double is 8-byte long, so we have 2*8 + terminating \0
       char *d2c;
       d2c = (char *) &a;
       char *n = buf;
       int i;
       for(i = 0; i < 8; i++)
       {
          sprintf(n, "%02X", *d2c++);
          n += 2;
       } 
       *(n) = '\0';
    }
    

    This seems work, however, I'm not sure how to convert the resulting string back to double. Please advise :)

  • Sparr
    Sparr about 15 years
    looks like strager beat me to this particular approach, and with more applicable implementation
  • Ali
    Ali over 8 years
    @Jahid The question asked for double and not for long double. If you wish to do it for long double, you need the "%LA" conversion specifier. You may want to upvote my answer now.