64bit binary string to double

Hi all, I have binary string like this "0011010000110000001100010011000000000000000000000011111101000011". I need to convert it to double. The string may be less that 64 digits.

I tried using this function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
double convert(int digits, string binaryNumber)        
{                                                           
   double result = 0.0f;
   if(binaryNumber[digits-1]=='1'){
        result = 1.0f;                    
   }else{
        result = 0.0f;
   }
   printf("%c : %d : %.0f : %.0f\n",binaryNumber[digits-1],0,pow(2.0, 0),result);
   for(int x = 1; x < digits; x++)
    {
        char temp = binaryNumber[digits-1-x];
        
        
        if(temp == '1')
        {
            if(x != 0)
            {
                result+= floor(pow(2.0, x));
            }
        }
        printf("%c : %d : %.5f : %.5f\n",temp,x,pow(2.0, x),result);
    }
    
    return result;


The result is
bin:digit:pow(2,digit)       : restult+=pow(2,digit)
====================================================
...
1 : 40 : 1099511627776.00000 : 1305670074179.00000
0 : 41 : 2199023255552.00000 : 1305670074179.00000
0 : 42 : 4398046511104.00000 : 1305670074179.00000
0 : 43 : 8796093022208.00000 : 1305670074179.00000
1 : 44 : 17592186044416.00000 : 18897856118595.00000
1 : 45 : 35184372088832.00000 : 54082228207427.00000
0 : 46 : 70368744177664.00000 : 54082228207427.00000
0 : 47 : 140737488355328.00000 : 54082228207427.00000
0 : 48 : 281474976710656.00000 : 54082228207427.00000
0 : 49 : 562949953421312.00000 : 54082228207427.00000
0 : 50 : 1125899906842624.00000 : 54082228207427.00000
0 : 51 : 2251799813685248.00000 : 54082228207427.00000
1 : 52 : 4503599627370496.00000 : 4557681855577923.00000
1 : 53 : 9007199254740992.00000 : 13564881110318916.00000
0 : 54 : 18014398509481984.00000 : 13564881110318916.00000
0 : 55 : 36028797018963968.00000 : 13564881110318916.00000
0 : 56 : 72057594037927936.00000 : 13564881110318916.00000
0 : 57 : 144115188075855872.00000 : 13564881110318916.00000
1 : 58 : 288230376151711744.00000 : 301795257262030656.00000
0 : 59 : 576460752303423488.00000 : 301795257262030656.00000
1 : 60 : 1152921504606846976.00000 : 1454716761868877568.00000
1 : 61 : 2305843009213693952.00000 : 3760559771082571776.00000
0 : 62 : 4611686018427387904.00000 : 3760559771082571776.00000
0 : 63 : 9223372036854775808.00000 : 3760559771082571776.00000
3760559771082571776


the result is correct until digit 53: 4557681855577923 + 9007199254740992 = 13564881110318916. 2 + 3 = 6.

i also tried this
1
2
3
double value = bitset<64>(string(binaryNumber)).to_ulong();

   return value;


but it didn't work

IOT/Abort trap(coredump)

i'm running it on AIX 64bit

I would like to thank in advance anyone who will help..
Last edited on
Where did the string come from?

EDIT: Code deleted
What is going on here??
This forum is NOT showing code properly
Last edited on
Finite precision. The floating point needs to store an exponent, so you can't use all the bits for the mantissa.
Maybe long double could work. However you may want to use a bignum library instead.

Also, change the computation algorithm, pow is overkill an add error. Use Horner's method.
thank you all for your responses..

@kbw: For example i have 8 numbers, i convert each of them to 8bit binary and concat the result. the result is the input for the function above.

@ne555: Now I've changed the algorithm to something like ((A*256+B)*256+C)*256+D. Where ABC is a number. I also use unsigned long long int
data type, instead of double. It works, but the problem now is I cant return -1 when there is an invalid value. return 0 is not correct. Program abort or return null is preferred. Any idea how to handle this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
unsigned long long int RawToDec(char* vInput){
     int vInt[8];
     char * vTemp; 
     string s(vInput);
     unsigned long long int vResult = 0;   
     int i = 0; 
     if(strspn(vInput,",0123456789")!=strlen(vInput)){
          return NULL???;
     }

     cleanInput(vInput);
     if(s.find(",",0)>s.size()-1){
          return atoi(vInput);
     }
     vTemp = strtok (vInput,",");                           
     while (vTemp != NULL){
                 vInt[i]=atoi(vTemp);
                 vTemp = strtok(NULL,",");                     
                 i++;   
     }
     int x=1;
     vResult = vInt[0]*256;
     for(x=1;x<i-1;x++){
          vResult += vInt[x];
          vResult *=256;
     }
     vResult += vInt[x];                    
     return vResult;
}

The argument for the function looks like this : 52,48,49,48,0,0,63,67

Once again, thank you so much for your responses.
Throw an exception.
I'm not really familiar with c++, but I think exception won't make me enable to return -1, right?

By the way, invalid value is very very unlikely. It just for worst case scenario. I don't want something invalid pass through unnoticed. Right now I just use exit(1).

I use the function for datastage routine, so datastage job will be aborted.
Last edited on
If all possible return values are valid, to return errors you can either have another parameter that callers should check before they try to use the returned value, or throw an exception and catch that.
Topic archived. No new replies allowed.