自己动手写C语言浮点数转换字符串函数(转)

前几天,应一个小友要求,写了几个字符串转换函数帮助其进行语言学习,自觉其中的几个函数还比较满意,故发布在此,可供初学者参考。

    浮点数转换字符串函数说简单也简单,说麻烦,也够烦心的,关键看你如何写了。简单点的几十行代码就行,复杂点的恐怕就的几百行代码了。如果还要考虑移植性、可读性甚至可维护性等就更麻烦的了。我一贯认为,一些事务性的项目应着重考虑移植性、可读性和可维护性等,而常用的带点系统性质的函数代码就应该以执行效率为主。

    本文的浮点数转换字符串函数还是比较复杂的,基本可算得上较低层次的转换。由于我已经习惯了用BCB写C/C++代码,因此我写的浮点数转换字符串函数是80位扩展精度浮点数的,但那个小友拿回去试了一下,说他用的VC不支持80位扩展精度浮点数,虽然能定义long double变量,但实际上还是64位的,我只好又重写了一个64位双精度浮点数的,2个版本使用条件编译,这也算得上是移植性吧,呵呵。

    下面是浮点数转换字符串函数的全部代码:

 

[cpp]   view plain copy print ?
  1. #define USE_EXTENDED  
  2.   
  3. /*************************************************************************** 
  4. * 定义浮点数转换字符串结构                                                 * 
  5. ***************************************************************************/  
  6. typedef struct  
  7. {  
  8.     SHORT   exponent;   /* 指数(整数位数) */  
  9.     BYTE    negative;   /* 负数(0正,1负)*/  
  10.     CHAR    digits[21]; /* 十进制整数字串 */  
  11. }FloatRec;  
  12.   
  13. #define F_DEFDECIMALS   6  
  14. #define F_MAXDECIMALS   100  
  15.   
  16. #ifdef  USE_EXTENDED  
  17.   
  18. #define F_MAXPRECISION  19  
  19. #define F_CONEXPONENT   0x3fff  
  20.   
  21. typedef long double         EXTENDED, *PExtended, *PEXTENDED;  
  22.   
  23. #include <pshpack2.h>  
  24.   
  25. typedef struct  
  26. {  
  27.     UINT64 mantissa;  
  28.     USHORT exponent;  
  29. }_Extended;  
  30.   
  31. #include <poppack.h>  
  32.   
  33. static CONST _Extended _tab0[] =  
  34. {  
  35.     {0x8000000000000000, 0x3FFF},   /* 10**0 */  
  36.     {0xA000000000000000, 0x4002},   /* 10**1 */  
  37.     {0xC800000000000000, 0x4005},   /* 10**2 */  
  38.     {0xFA00000000000000, 0x4008},   /* 10**3 */  
  39.     {0x9C40000000000000, 0x400C},   /* 10**4 */  
  40.     {0xC350000000000000, 0x400F},   /* 10**5 */  
  41.     {0xF424000000000000, 0x4012},   /* 10**6 */  
  42.     {0x9896800000000000, 0x4016},   /* 10**7 */  
  43.     {0xBEBC200000000000, 0x4019},   /* 10**8 */  
  44.     {0xEE6B280000000000, 0x401C},   /* 10**9 */  
  45.     {0x9502F90000000000, 0x4020},   /* 10**10 */  
  46.     {0xBA43B74000000000, 0x4023},   /* 10**11 */  
  47.     {0xE8D4A51000000000, 0x4026},   /* 10**12 */  
  48.     {0x9184E72A00000000, 0x402A},   /* 10**13 */  
  49.     {0xB5E620F480000000, 0x402D},   /* 10**14 */  
  50.     {0xE35FA931A0000000, 0x4030},   /* 10**15 */  
  51.     {0x8E1BC9BF04000000, 0x4034},   /* 10**16 */  
  52.     {0xB1A2BC2EC5000000, 0x4037},   /* 10**17 */  
  53.     {0xDE0B6B3A76400000, 0x403A},   /* 10**18 */  
  54.     {0x8AC7230489E80000, 0x403E},   /* 10**19 */  
  55.     {0xAD78EBC5AC620000, 0x4041},   /* 10**20 */  
  56.     {0xD8D726B7177A8000, 0x4044},   /* 10**21 */  
  57.     {0x878678326EAC9000, 0x4048},   /* 10**22 */  
  58.     {0xA968163F0A57B400, 0x404B},   /* 10**23 */  
  59.     {0xD3C21BCECCEDA100, 0x404E},   /* 10**24 */  
  60.     {0x84595161401484A0, 0x4052},   /* 10**25 */  
  61.     {0xA56FA5B99019A5C8, 0x4055},   /* 10**26 */  
  62.     {0xCECB8F27F4200F3A, 0x4058},   /* 10**27 */  
  63.     {0x813F3978F8940984, 0x405C},   /* 10**28 */  
  64.     {0xA18F07D736B90BE5, 0x405F},   /* 10**29 */  
  65.     {0xC9F2C9CD04674EDF, 0x4062},   /* 10**30 */  
  66.     {0xFC6F7C4045812296, 0x4065}    /* 10**31 */  
  67. };  
  68.   
  69. static CONST _Extended _tab1[] =  
  70. {  
  71.     {0x9DC5ADA82B70B59E, 0x4069},   /* 10**32 */  
  72.     {0xC2781F49FFCFA6D5, 0x40D3},   /* 10**64 */  
  73.     {0xEFB3AB16C59B14A3, 0x413D},   /* 10**96 */  
  74.     {0x93BA47C980E98CE0, 0x41A8},   /* 10**128 */  
  75.     {0xB616A12B7FE617AA, 0x4212},   /* 10**160 */  
  76.     {0xE070F78D3927556B, 0x427C},   /* 10**192 */  
  77.     {0x8A5296FFE33CC930, 0x42E7},   /* 10**224 */  
  78.     {0xAA7EEBFB9DF9DE8E, 0x4351},   /* 10**256 */  
  79.     {0xD226FC195C6A2F8C, 0x43BB},   /* 10**288 */  
  80.     {0x81842F29F2CCE376, 0x4426},   /* 10**320 */  
  81.     {0x9FA42700DB900AD2, 0x4490},   /* 10**352 */  
  82.     {0xC4C5E310AEF8AA17, 0x44FA},   /* 10**384 */  
  83.     {0xF28A9C07E9B09C59, 0x4564},   /* 10**416 */  
  84.     {0x957A4AE1EBF7F3D4, 0x45CF},   /* 10**448 */  
  85.     {0xB83ED8DC0795A262, 0x4639}    /* 10**480 */  
  86. };  
  87.   
  88. static CONST _Extended _tab2[] =  
  89. {  
  90.     {0xE319A0AEA60E91C7, 0x46A3},   /* 10**512 */  
  91.     {0xC976758681750C17, 0x4D48},   /* 10**1024 */  
  92.     {0xB2B8353B3993A7E4, 0x53ED},   /* 10**1536 */  
  93.     {0x9E8B3B5DC53D5DE5, 0x5A92},   /* 10**2048 */  
  94.     {0x8CA554C020A1F0A6, 0x6137},   /* 10**2560 */  
  95.     {0xF9895D25D88B5A8B, 0x67DB},   /* 10**3072 */  
  96.     {0xDD5DC8A2BF27F3F8, 0x6E80},   /* 10**3584 */  
  97.     {0xC46052028A20979B, 0x7525},   /* 10**4096 */  
  98.     {0xAE3511626ED559F0, 0x7BCA}    /* 10**4608 */  
  99. };  
  100.   
  101. static CONST EXTENDED _conPrec = 1E19;  
  102.   
  103. #else   // USE_EXTENDED  
  104.   
  105. #define F_MAXPRECISION  17  
  106. #define F_CONEXPONENT   0x03ff  
  107.   
  108. typedef double      EXTENDED, *PExtended, *PEXTENDED;  
  109.   
  110. static CONST UINT64 _tab0[] =  
  111. {  
  112.     {0x3FF0000000000000},   /* 10**0 */  
  113.     {0x4024000000000000},   /* 10**1 */  
  114.     {0x4059000000000000},   /* 10**2 */  
  115.     {0x408F400000000000},   /* 10**3 */  
  116.     {0x40C3880000000000},   /* 10**4 */  
  117.     {0x40F86A0000000000},   /* 10**5 */  
  118.     {0x412E848000000000},   /* 10**6 */  
  119.     {0x416312D000000000},   /* 10**7 */  
  120.     {0x4197D78400000000},   /* 10**8 */  
  121.     {0x41CDCD6500000000},   /* 10**9 */  
  122.     {0x4202A05F20000000},   /* 10**10 */  
  123.     {0x42374876E8000000},   /* 10**11 */  
  124.     {0x426D1A94A2000000},   /* 10**12 */  
  125.     {0x42A2309CE5400000},   /* 10**13 */  
  126.     {0x42D6BCC41E900000},   /* 10**14 */  
  127.     {0x430C6BF526340000},   /* 10**15 */  
  128.     {0x4341C37937E08000},   /* 10**16 */  
  129.     {0x4376345785D8A000},   /* 10**17 */  
  130.     {0x43ABC16D674EC800},   /* 10**18 */  
  131.     {0x43E158E460913D00},   /* 10**19 */  
  132.     {0x4415AF1D78B58C40},   /* 10**20 */  
  133.     {0x444B1AE4D6E2EF50},   /* 10**21 */  
  134.     {0x4480F0CF064DD592},   /* 10**22 */  
  135.     {0x44B52D02C7E14AF7},   /* 10**23 */  
  136.     {0x44EA784379D99DB4},   /* 10**24 */  
  137.     {0x45208B2A2C280291},   /* 10**25 */  
  138.     {0x4554ADF4B7320335},   /* 10**26 */  
  139.     {0x4589D971E4FE8402},   /* 10**27 */  
  140.     {0x45C027E72F1F1281},   /* 10**28 */  
  141.     {0x45F431E0FAE6D722},   /* 10**29 */  
  142.     {0x46293E5939A08CEA},   /* 10**30 */  
  143.     {0x465F8DEF8808B024}    /* 10**31 */  
  144. };  
  145.   
  146. static CONST UINT64 _tab1[] =  
  147. {  
  148.     {0x4693B8B5B5056E17},   /* 10**32 */  
  149.     {0x4D384F03E93FF9F5},   /* 10**64 */  
  150.     {0x53DDF67562D8B363},   /* 10**96 */  
  151.     {0x5A827748F9301D32},   /* 10**128 */  
  152.     {0x6126C2D4256FFCC3},   /* 10**160 */  
  153.     {0x67CC0E1EF1A724EB},   /* 10**192 */  
  154.     {0x6E714A52DFFC679A},   /* 10**224 */  
  155.     {0x75154FDD7F73BF3C},   /* 10**256 */  
  156.     {0x7BBA44DF832B8D46},   /* 10**288 */  
  157. };  
  158.   
  159. static CONST EXTENDED _conPrec = 1E17;  
  160.   
  161. #endif      // !USE_EXTENDED  
  162.   
  163. static CONST UINT64 _cvttab[F_MAXPRECISION] =  
  164. {  
  165. #ifdef  USE_EXTENDED  
  166.     0xDE0B6B3A7640000, 0x16345785D8A0000,   
  167. #endif  
  168.     0x02386F26FC10000, 0x0038D7EA4C68000, 0x0005AF3107A4000, 0x00009184E72A000,  
  169.     0x00000E8D4A51000, 0x00000174876E800, 0x0000002540BE400, 0x00000003B9ACA00,  
  170.     0x000000005F5E100, 0x000000000989680, 0x0000000000F4240, 0x0000000000186A0,  
  171.     0x000000000002710, 0x0000000000003E8, 0x000000000000064, 0x00000000000000A,  
  172.     0x000000000000001  
  173. };  
  174.   
  175. #define DECIMAL_EXP(exponent)   ((((exponent - F_CONEXPONENT) * 0x4d10) >> 16) + 1)  
  176.   
  177. static VOID AdjFloatDigits(UINT64 value, INT precision, INT decimals, FloatRec *rec)  
  178. {  
  179.     INT i;  
  180.     // value是F_MAXPRECISION位十进制整数,故从最高位开始转换为数字串  
  181.     for (i = 0; value; i ++)  
  182.     {  
  183.         rec->digits[i] = (CHAR)((value / _cvttab[i]) | 0x30);  
  184.         value %= _cvttab[i];  
  185.     }  
  186.     memset(rec->digits + i, 0, F_MAXPRECISION - i);  
  187.     // 下面对数字串作精度处理  
  188.     // 如果总的精度小于0,数字串为空串,该数字转换为'0'  
  189.     if ((i = (rec->exponent + decimals)) < 0)  
  190.     {  
  191.         rec->exponent = rec->negative = rec->digits[0] = 0;  
  192.         return;  
  193.     }  
  194.     if (i > precision) i = precision;  
  195.     // 如果精度位数小于18,同时该位大于等于'5',四舍五入  
  196.     if (i < F_MAXPRECISION && rec->digits[i] >= '5')  
  197.     {  
  198.         do  
  199.         {  
  200.             rec->digits[i --] = 0;  
  201.             rec->digits[i] ++;  
  202.         }while (i >= 0 && rec->digits[i] > '9');  
  203.         if (i < 0)  
  204.         {  
  205.             rec->digits[0] = '1';  
  206.             rec->exponent ++;  
  207.         }  
  208.     }  
  209.     // 否则,去掉数字串尾部多余的'0'  
  210.     else  
  211.     {  
  212.         if (i > F_MAXPRECISION) i = F_MAXPRECISION;  
  213.         do rec->digits[i --] = 0;  
  214.         while (i >= 0 && rec->digits[i] == '0');  
  215.         if (i < 0) rec->negative = 0;  
  216.     }  
  217. }  
  218.   
  219. #ifdef  USE_EXTENDED  
  220.   
  221. // 解析扩展精度浮点数为十进制字符串,并存入浮点数记录中  
  222. // 参数:浮点数指针,精度,小数位,浮点数记录  
  223. VOID FloatResolve(PEXTENDED pvalue, INT precision, INT decimals, FloatRec *rec)  
  224. {  
  225.     INT power;  
  226.     EXTENDED val;  
  227.   
  228.     // 79位:扩展精度浮点数符号位  
  229.     rec->negative = ((_Extended*)pvalue)->exponent >> 15;  
  230.     // 64-78位:扩展精度浮点数阶码(阶码 - 0x3fff = 二进制指数)  
  231.     rec->exponent = ((_Extended*)pvalue)->exponent & 0x7fff;  
  232.     if (!rec->exponent)          // *pvalue = 0  
  233.     {  
  234.         rec->negative = rec->digits[0] = 0;  
  235.         return;  
  236.     }  
  237.     if (rec->exponent == 0x7fff)// *pvalue = nan or inf  
  238.     {  
  239.         if (!((*(LPBYTE)pvalue + 7) & 0x80) || !(*(PUINT64)pvalue & 0x7fffffffffffffff))  
  240.         {  
  241.             lstrcpyA(rec->digits, "INF");  
  242.         }  
  243.         else  
  244.         {  
  245.             rec->exponent ++;  
  246.             rec->negative = 0;  
  247.             lstrcpyA(rec->digits, "NAN");  
  248.         }  
  249.         return;  
  250.     }  
  251.     // 阶码转换为十进制指数  
  252.     rec->exponent = DECIMAL_EXP(rec->exponent);  
  253.     // 0-63位:扩展精度浮点数尾数转换成F_MAXPRECISION位十进制浮点整数格式  
  254.     val = *pvalue;  
  255.     *((LPBYTE)&val + 9) &= 0x7f;// val = fabs(*pvalue)  
  256.     power = F_MAXPRECISION - rec->exponent;  
  257.     if (power > 0)               // if (power > 0) val *= (10**power)  
  258.     {  
  259.         val *= *(PEXTENDED)&_tab0[power & 31];  
  260.         power >>= 5;          // power /= 32;  
  261.         if (power)  
  262.         {  
  263.             if (power & 15)  
  264.                 val *= *(PEXTENDED)&_tab1[(power & 15) - 1];  
  265.             power >>= 4;      // power /= 16;  
  266.             if (power)  
  267.                 val *= *(PEXTENDED)&_tab2[power - 1];  
  268.         }  
  269.     }  
  270.     else if (power < 0)          // if (power < 0) val /= (10**power)  
  271.     {  
  272.         power = -power;  
  273.         val /= *(PEXTENDED)&_tab0[power & 31];  
  274.         power >>= 5;          // power /= 32;  
  275.         if (power)  
  276.         {  
  277.             if (power & 15)  
  278.                 val /= *(PEXTENDED)&_tab1[(power & 15) - 1];  
  279.             power >>= 4;      // power /= 16;  
  280.             if (power)  
  281.                 val /= *(PEXTENDED)&_tab2[power - 1];  
  282.         }  
  283.     }  
  284.     val += 0.5;                 // 四舍五入  
  285.     if (val >= _conPrec)  
  286.     {  
  287.         val /= 10;  
  288.         rec->exponent ++;  
  289.     }  
  290.     // 调整并转换扩展精度浮点数尾数的整数部分rec->digits  
  291.     AdjFloatDigits(*(PUINT64)&val >> ((((_Extended*)&val)->exponent - 0x3fff) ^ 0x3f),  
  292.         precision, decimals, rec);  
  293. }  
  294.   
  295. #else   // USE_EXTENDED  
  296.   
  297. // 解析双精度浮点数为十进制字符串,并存入浮点数记录中  
  298. // 参数:浮点数指针,精度,小数位,浮点数记录  
  299. VOID FloatResolve(PEXTENDED pvalue, INT precision, INT decimals, FloatRec *rec)  
  300. {  
  301.     INT power;  
  302.     EXTENDED val;  
  303.   
  304.     // 63位:双精度浮点数符号位  
  305.     rec->negative = *((LPBYTE)pvalue + 7) >> 7;  
  306.     // 52-62位:双精度浮点数阶码(阶码 - 0x3ff = 二进制指数)  
  307.     rec->exponent = (*(PUINT64)pvalue >> 52) & 0x7ff;  
  308.     if (!rec->exponent)          // *pvalue = 0  
  309.     {  
  310.         rec->negative = rec->digits[0] = 0;  
  311.         return;  
  312.     }  
  313.     if (rec->exponent == 0x7ff)// *pvalue = nan or inf  
  314.     {  
  315.         if ((*(PUINT64)pvalue & 0xfffffffffffff) == 0)  
  316.         {  
  317.             lstrcpyA(rec->digits, "INF");  
  318.         }  
  319.         else  
  320.         {  
  321.             rec->exponent ++;  
  322.             rec->negative = 0;  
  323.             lstrcpyA(rec->digits, "NAN");  
  324.         }  
  325.         return;  
  326.     }  
  327.     // 阶码转换为十进制指数  
  328.     rec->exponent = DECIMAL_EXP(rec->exponent);  
  329.     // 0-51位:双精度浮点数尾数转换成F_MAXPRECISION位十进制浮点整数格式  
  330.     val = *pvalue;  
  331.     *((LPBYTE)&val + 7) &= 0x7f;// val = fabs(*pvalue)  
  332.     power = F_MAXPRECISION - rec->exponent;  
  333.     if (power > 0)               // if (power > 0) val *= (10**power)  
  334.     {  
  335.         val *= *(PEXTENDED)&_tab0[power & 31];  
  336.         power >>= 5;          // power /= 32;  
  337.         if (power)  
  338.             val *= *(PEXTENDED)&_tab1[power - 1];  
  339.     }  
  340.     else if (power < 0)          // if (power < 0) val /= (10**power)  
  341.     {  
  342.         power = -power;  
  343.         val /= *(PEXTENDED)&_tab0[power & 31];  
  344.         power >>= 5;          // power /= 32;  
  345.         if (power)  
  346.             val /= *(PEXTENDED)&_tab1[power - 1];  
  347.     }  
  348.   
  349.     // 16位十进制浮点整数四舍五入  
  350.     val += 0.5;  
  351.     if (val >= _conPrec)  
  352.     {  
  353.         val /= 10;  
  354.         rec->exponent ++;  
  355.     }  
  356.     // 调整并转换扩展精度浮点数尾数的整数部分rec->digits  
  357.     // 清除52-63位,加隐藏的高位,F_MAXPRECISION=17,高位超过52位,所以左移  
  358.     AdjFloatDigits(((*(PUINT64)&val & 0x000fffffffffffff) | 0x0010000000000000) <<  
  359.         -(52 - ((*(PUINT64)&val >> 52) - 0x3ff)), precision, decimals, rec);  
  360. }  
  361.   
  362. #endif  // !USE_EXTENDED  
  363.   
  364. // 输出指数字符串到buffer,返回指数字符串长度  
  365. INT PutExponent(LPSTR buffer, CONST FloatRec *rec)  
  366. {  
  367.     LPSTR p = buffer;  
  368.     INT e, exp = rec->digits[0]? rec->exponent - 1 : 0;  
  369.     *p ++ = rec->negative & 0x80? 'E' : 'e';  
  370.     if (exp < 0)  
  371.     {  
  372.         exp = -exp;  
  373.         *p ++ = '-';  
  374.     }  
  375.     else *p ++ = '+';  
  376.     if ((e = (exp / 1000)) != 0)  
  377.     {  
  378.         *p ++ = e + 0x30;  
  379.         exp %= 1000;  
  380.     }  
  381.     *p ++ = exp / 100 + 0x30;  
  382.     exp %= 100;  
  383.     *(PUSHORT)p = (((exp % 10) << 8) | (exp / 10)) + 0x3030;  
  384.     return (INT)(p - buffer + 2);  
  385. }  
  386.   
  387. // 浮点数转换为字符串。参数:字符串,浮点数  
  388. LPSTR FloatToStr(LPSTR str, EXTENDED value)  
  389. {  
  390.     INT exp;  
  391.     FloatRec rec;  
  392.     LPSTR pd = rec.digits;  
  393.     LPSTR ps = str;  
  394.   
  395.     // 解析浮点数,并将信息保存在rec  
  396.     FloatResolve(&value, 15, 9999, &rec);  
  397.     // 打印负数符号  
  398.     if (rec.negative) *ps ++ = '-';  
  399.     // NAN or INF  
  400.     if (*pd > '9')                 
  401.     {  
  402.         memcpy(ps, pd, 4);  
  403.         return str;  
  404.     }  
  405.     exp = rec.exponent;  
  406.     // 如果十进制指数大于15或者小于-3,转换为指数形式  
  407.     if (exp > 15 || exp < -3)   
  408.     {  
  409.         *ps ++ = *pd ++;  
  410.         if (*pd)  
  411.             for (*ps ++ = '.'; *pd; *ps ++ = *pd ++);  
  412.         ps += PutExponent(ps, &rec);  
  413.         *ps = 0;  
  414.         return str;  
  415.     }  
  416.     // 否则,转换为小数形式  
  417.     if (exp <= 0)  
  418.     {  
  419.         *ps ++ = '0';  
  420.         if (*pd)  
  421.         {  
  422.             for (*ps ++ = '.'; exp < 0; *ps ++ = '0', exp ++);  
  423.             while (*ps ++ = *pd ++);  
  424.         }  
  425.         else *ps = 0;  
  426.     }  
  427.     else  
  428.     {  
  429.         for (; exp > 0 && *pd; *ps ++ = *pd ++, exp --);  
  430.         if (*pd)  
  431.         {  
  432.             *ps ++ = '.';  
  433.             while (*ps ++ = *pd ++);  
  434.         }  
  435.         else  
  436.         {  
  437.             memset(ps, '0', exp);  
  438.             ps[exp] = 0;  
  439.         }  
  440.     }  
  441.     return str;  
  442. }  

    2个版本的代码加起来很长,但还有个自写的springf函数(下篇文章开始介绍)也要用到本文除FloatToSt函数外的全部代码。

 

    代码开头的USE_EXTENDED为编译条件,如果你的编译系统不支持80位扩展精度浮点数,可将该定义注释掉。

    前面说了,由于该代码主要是学习用的,因此数据转换层次较低,涉及到的有关浮点数格式的知识,可在网上搜索到。当然,知道是一回事,而具体怎样去操作则又是另一回事了,一些关键地方,我都作了较详细的注释,相信能对初学者正确理解浮点数格式有所帮助。例如,如何在不调用C有关函数,不使用汇编而快速的求一个浮点数的绝对值?本文代码就直接对浮点数进行操作:*((LPBYTE)&val + 7) &= 0x7f;(双精度浮点数)和*((LPBYTE)&val + 9) &= 0x7f;(扩展精度浮点数),也就是直接将浮点数的最高位置零,这当然比什么if (val < 0) val = -val语句快多了。不过,如果你要说后者的可移植性好,那我就无话可说了。要说可移植性,前者也可办到的,修改一下:*((LPBYTE)&val + sizeof(val) - 1) &= 0x7f;不就行了么,除非浮点数格式规则改变。只不过本文代码主要用来学习,用显式的方式更有意义。

    80位扩展精度浮点数的有效数字为19位,而64位双精度浮点数有效数字为15 - 16位,本文的解析函数FloatResolve分别用了19位和17位的最大转换精度,尽可能的多显示几位,这主要是为自写的sprintf函数(另文介绍)做准备的,本文的浮点数转换字符串函数FloatToStr只用了最大15位的精度。

    下面是个很简单的调用例子:

 

[cpp]   view plain copy print ?
  1. int main(int argc, char* argv[])  
  2. {  
  3.     CHAR s[32];  
  4.     UINT64 inf = 0x7ff0000000000000;  
  5.     double v = -1.230E45;  
  6.     INT a, b;  
  7.   
  8.     puts(FloatToStr(s, -10000));  
  9.     puts(FloatToStr(s, 123456789012345678));  
  10.     puts(FloatToStr(s, 1234567890.12345678));  
  11.     puts(FloatToStr(s, 0.0001234567890));  
  12.     puts(FloatToStr(s, -0.00001234567890));  
  13.     puts(FloatToStr(s, v));  
  14.     puts(FloatToStr(s, 0));  
  15.     puts(FloatToStr(s, *(double*)&inf));  
  16.   
  17.     system("pause");  
  18.     return 0;  
  19. }  
[plain]   view plain copy print ?
  1.   

    下面是运行结果:

 

[cpp]   view plain copy print ?
  1. -10000  
  2. 1.23456789012346e+017  
  3. 1234567890.12346  
  4. 0.000123456789  
  5. -1.23456789e-005  
  6. -1.23e+045  
  7. 0  
  8. INF  
  9. 请按任意键继续. . .  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值