double to hex string & hex string to double

后端 未结 9 1380
南方客
南方客 2021-01-02 20:51

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 *          


        
相关标签:
9条回答
  • 2021-01-02 21:24

    You want to use a union and avoid this bad habit:

    char *d2c;

    d2c = (char *) &a;

    For just printing its not bad, its when you try to modify d2c and then use a is when you get into trouble. (same is true for any two variables or pointers (or arrays) sharing the same (theoretical) memory.

    union
    {
        double f;
        unsigned long ul;
    } myun;
    
    myun.f = a;
    printf("0x%lX",myun.ul);
    
    to go the other way (scanf is also a very dangerous function that should be avoided).
    
    myun.ul=strtoul(string,NULL,16);
    a=myun.f;
    
    0 讨论(0)
  • 2021-01-02 21:34
    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;
    
    0 讨论(0)
  • 2021-01-02 21:35

    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;
    
    }
    
    0 讨论(0)
  • 2021-01-02 21:39
    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;
    }
    
    0 讨论(0)
  • 2021-01-02 21:42

    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)

    0 讨论(0)
  • 2021-01-02 21:43
    #include <stdio.h>
    main() {
      union double_ull_t {
        double d;
        unsigned long long u;
      } x;
      scanf("%lf",&x.d);
      printf("%016llX %lf\n",x.u,x.d);
      scanf("%016llX",&x.u);
      printf("%016llX %lf\n",x.u,x.d);
    }
    

    Maybe not the most efficient solution, but the easiest to code.

    0 讨论(0)
提交回复
热议问题