给 个 只 支 持 10^15 以 上 的 大 数 的 版 本,关 于 小 数 的 算 法 还 在 整 理 中:#include <stdio.h> /*#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*/ 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 big_dec_to_string( 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 = 1e307; char dest[800]; char cmp[800]; if( 0 == double_to_string( src, dest, sizeof(dest) ) ){ printf("/nOk : %s/n", dest); } sprintf(cmp, "%f", 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; unsigned short exp = 0; unsigned long long value = 0; short exp_exp = 0;// the decimal exp short temp_short = 0; unsigned char big_dec[800]; 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 = to_big_dec( -1 * exp, big_dec, sizeof(big_dec) ); }else{ big_dec_flag = to_big_dec( exp, big_dec, sizeof(big_dec) ); } if( exp > 0 ){ 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 <= 680 )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 <= 780 )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; } input:double src = 1e307; output: Ok : 999999999999999986031059760256457771700264183812636387524966073588356 58526727438490648464142289606667863792803926546153933531728502521033362759523706 15397010730691664689375178569039851073146339641623266071126720011020169553304018 596457812688561947201171488461172921822139066929851282122002676667750021070848 sprintf(): 999999999999999990000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000.0 00000