#include /*#define BYTE_SWAP #ifdef BYTE_SWAP*/ typedef struct{ unsigned long long tail1 :52;//Mantissa unsigned long long exp :11; //Exp unsigned long long sign :1; //Sign }BITS; typedef union { double d; BITS bits; }DATA; /*#else typedef union { double d; struct { unsigned int sign :1; //Sign unsigned short exp :11; //Exp long long int tail1 :52;//Mantissa }bits; }DATA; #endif*/ #define INT_NUM 20 #define MAX_BUFFER 3000 int double_to_string( double src, unsigned char *dest, int buflen ); int to_big_dec( short exp, unsigned char *dest, int buflen ); int int_to_dec( long long src, unsigned char *dest, int buflen ); int mult_big_dec( unsigned char *big_dec, int big_dec_buflen, int big_dec_flag, unsigned char *value_dec , int value_dec_buflen, int value_dec_index ); int div_big_dec( unsigned char *value_dec , int value_dec_buflen, int value_dec_index, short exp, unsigned char *big_dec, int big_dec_buflen); int big_dec_to_string( unsigned char *big_dec, int big_dec_buflen, int big_dec_flag, unsigned char *dest, int buflen ); int big_dec_to_string2( unsigned char *big_dec, int big_dec_buflen, int big_dec_flag, unsigned char *dest, int buflen ); int main(int num, char **args){ double src = -12324.5166151e-3; char dest[MAX_BUFFER]; char cmp[MAX_BUFFER]; if( 0 == double_to_string( src, dest, sizeof(dest) ) ){ printf("/nOk : %s/n", dest); } sprintf(cmp, "%.600f", src); printf("sprintf(): %s/n", cmp); return 0; } int double_to_string( double src, unsigned char *dest, int buflen ){ int index = 0; char sign = 0; short exp = 0; unsigned long long value = 0; short exp_exp = 0;// the decimal exp short temp_short = 0; unsigned char big_dec[MAX_BUFFER]; int big_dec_flag = 0; unsigned char value_dec[30]; int value_dec_index = 0; DATA my_data; if( buflen <= 0 )return -1; my_data.d = src; sign = (char)my_data.bits.sign;// if sign==0 ->+ ; else - exp = (unsigned short)my_data.bits.exp;// the E is next 11 bits exp -= 1023; if( sign != 0 ){ dest[index] = '-'; index++; if( index >= buflen )return -1; } exp -= 52;// let value * 2^52 // The value is from temp[1] to temp[7] ,starting at ending 4 bits of temp[1] if( 8 != sizeof( value ) ){ printf("not support long long int /n"); return -1; }// not support long long int value = my_data.bits.tail1; value += 0x0010000000000000; value_dec_index = int_to_dec( value, value_dec, sizeof(value_dec) ); if( exp < 0 ){ big_dec_flag = div_big_dec( value_dec , sizeof(value_dec), value_dec_index, -1*exp, big_dec, sizeof(big_dec)); if( 0 != big_dec_to_string2( big_dec, sizeof(big_dec), big_dec_flag, dest+index, buflen-index ) ){ return -1; } }else{ big_dec_flag = to_big_dec( exp, big_dec, sizeof(big_dec) ); big_dec_flag = mult_big_dec( big_dec, sizeof(big_dec), big_dec_flag, value_dec, sizeof(value_dec), value_dec_index ); if( 0 != big_dec_to_string( big_dec, sizeof(big_dec), big_dec_flag, dest+index, buflen-index ) ){ return -1; } } return 0; } int to_big_dec( short exp, unsigned char *dest, int buflen ){ int i,j,flag=0; if( buflen <= 0 )return -1; if( exp >= 2000 || buflen <= MAX_BUFFER )return -1; memset( dest, 0 ,buflen ); dest[ buflen-1 ] = 1; for( i = 3; i <= exp; i+=3 ){ for( j = 0; j <= flag; j++ ){ dest[buflen - 1 - j] *= 8; } for( j = 0; j <= flag; j++ ){ if( dest[buflen - 1 - j] >= 10 ){ dest[buflen - 1 - j - 1] += dest[buflen - 1 - j] / 10; dest[buflen - 1 - j] %= 10; if( j == flag ){ flag++; } } } } if( exp % 3 != 0 ){ i = exp % 3; switch(i){ case 1: i = 2; break; case 2: i = 4; break; } for( j = 0; j <= flag; j++ ){ dest[buflen - 1 - j] *= i; } for( j = 0; j <= flag; j++ ){ if( dest[buflen - 1 - j] >= 10 ){ dest[buflen - 1 - j - 1] += dest[buflen - 1 - j] / 10; dest[buflen - 1 - j] %= 10; if( j == flag ){ flag++; } } } } return flag; } int int_to_dec( long long src, unsigned char *dest, int buflen ){ int index=0; long long temp = 0; if( buflen <= 20 )return -1; memset( dest, 0 ,buflen ); while( src != 0 ){ temp = src / 10; dest[ buflen - 1 - index ] = src - temp * 10; index++; src = temp; } return index; } int mult_big_dec( unsigned char *big_dec, int big_dec_buflen, int big_dec_flag, unsigned char *value_dec, int value_dec_buflen, int value_dec_index ){ int i = 0; int flag = big_dec_flag; int j = 0; unsigned char *temp_big_dec; if( big_dec_buflen <= MAX_BUFFER )return -1; temp_big_dec = (char *) malloc( big_dec_buflen ); if( NULL == temp_big_dec )return -1; memset( temp_big_dec, 0, big_dec_buflen ); for( i = 0; i < value_dec_index; i++ ){ for( j = 0; j <= big_dec_flag; j++ ){ temp_big_dec[big_dec_buflen - 1 - j - i] += big_dec[big_dec_buflen - 1 - j] * value_dec[value_dec_buflen - 1 - i]; } flag++; for( j = 0; j <= flag; j++ ){ if( temp_big_dec[big_dec_buflen - 1 - j] >= 10 ){ temp_big_dec[big_dec_buflen - 1 - j - 1] += temp_big_dec[big_dec_buflen - 1 - j] / 10; temp_big_dec[big_dec_buflen - 1 - j] %= 10; if( j == flag ){ flag++; } } } } if( temp_big_dec[big_dec_buflen - 1 - flag] == 0 ){ flag--; } memcpy( big_dec, temp_big_dec, big_dec_buflen ); free( temp_big_dec ); return flag; } int big_dec_to_string( unsigned char *big_dec, int big_dec_buflen, int big_dec_flag, unsigned char *dest, int buflen ){ int index = 0; int i = 0; for( i = 0; i <= big_dec_flag; i++ ){ if(index >= buflen)return -1; dest[index] = big_dec[big_dec_buflen - 1 - big_dec_flag + i] + '0'; index++; } if(index >= buflen)return -1; dest[index] = '/0'; return 0; } int big_dec_to_string2( unsigned char *big_dec, int big_dec_buflen, int big_dec_flag, unsigned char *dest, int buflen ){ int index = 0; int i = 0; int zero_flag = 1; for( i = 0; i <= big_dec_flag; i++ ){ if(index >= buflen)return -1; if( i == INT_NUM && i <= big_dec_flag ){ dest[index] = '.'; index++; if(index >= buflen)return -1; dest[index] = big_dec[i] + '0'; index++; continue; } if( i >= INT_NUM || big_dec[i] != 0 ){ zero_flag = 0; } if( zero_flag ){ if( i == INT_NUM-1 ){ dest[index] = '0'; index++; } continue; } dest[index] = big_dec[i] + '0'; index++; } if(index >= buflen)return -1; dest[index] = '/0'; return 0; } int div_big_dec( unsigned char *value_dec , int value_dec_buflen, int value_dec_index, short exp, unsigned char *big_dec, int big_dec_buflen){ int i = 0; int index = value_dec_index; int big_dec_index = 0; int j = 0; if( value_dec_buflen <= 0 || big_dec_buflen <= 780 || exp < 0 || value_dec_index + exp/3 >= 780 ){ return -1; } memset( big_dec, 0, big_dec_buflen ); memcpy( big_dec + INT_NUM - value_dec_index, value_dec + value_dec_buflen - value_dec_index, value_dec_index ); big_dec_index = INT_NUM; for( i = 3; i <= exp; i+=3 ){ for( j = 0; j <= index; j++ ){ big_dec[big_dec_index - index + j + 1] += ( big_dec[big_dec_index - index + j] % 8 ) * 10; big_dec[big_dec_index - index + j] /= 8; if( big_dec[big_dec_index - index + j + 1] != 0 && j == index ){ index++; big_dec_index++; } } if( 0 == big_dec[big_dec_index - index] ){ index--; } } i = exp % 3; if( i != 0 ){ switch(i){ case 1: i = 2; break; case 2: i = 4; break; } for( j = 0; j <= index; j++ ){ big_dec[big_dec_index - index + j + 1] += ( big_dec[big_dec_index - index + j] % i ) * 10; big_dec[big_dec_index - index + j] /= i; if( big_dec[big_dec_index - index + j + 1] != 0 && j == index ){ index++; big_dec_index++; } } } return big_dec_index; }
input:
double src = -12324.5166151e-3;
output:
Ok : -12.3245166151000002940918420790694653987884521484375 sprintf(): -12.32451661510000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000