00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "fastval2str.h"
00018 #include <lib/numerics/num_math.h>
00019
00020
00021
00022
00023 static const char *_hexdig="YZ0123456789abcdefGH";
00024 static const char *hexdig=_hexdig+2;
00025
00026
00027
00028
00029
00030
00031 template<typename T>static char *_UInt2String(char *dest,T val,char base)
00032 {
00033
00034 switch(base)
00035 {
00036 case 8:
00037 {
00038 *dest++='0';
00039 if(!val) break;
00040
00041 int shift =
00042 (sizeof(T)*8)%3==0 ? (sizeof(T)*8) :
00043 (sizeof(T)*8+1)%3==0 ? (sizeof(T)*8+1) : (sizeof(T)*8+2);
00044 Assert(!(shift%3));
00045 while(shift)
00046 {
00047 shift-=3;
00048 uchar c=(uchar)((val>>shift)&7U);
00049 if(c)
00050 { *dest++=(char)c+'0'; break; }
00051 }
00052 while(shift)
00053 {
00054 shift-=3;
00055 *dest++=(char)((val>>shift)&0x7U)+'0';
00056 }
00057 } break;
00058 case 10:
00059 {
00060 if(!val)
00061 { *dest++='0'; break; }
00062 static const T div0 =
00063 sizeof(T)==1 ? (T)100U :
00064 sizeof(T)==2 ? (T)10000U :
00065 sizeof(T)==4 ? (T)1000000000LU :
00066 (T)10000000000000000000LLU;
00067 T div=div0;
00068 uchar c;
00069 while(div)
00070 {
00071 c=(uchar)(val/div);
00072 if(c) goto start;
00073 div/=10;
00074 }
00075 while(div)
00076 {
00077 c=(uchar)(val/div);
00078 start:
00079 *dest++=(char)c+'0';
00080 val-=c*div;
00081 div/=10;
00082 }
00083 } break;
00084 case 16:
00085 *dest++='0';
00086 *dest++='x';
00087
00088 case 0:
00089 {
00090 if(!val)
00091 { *dest++='0'; break; }
00092 int shift=sizeof(T)*8;
00093 while(shift)
00094 {
00095 shift-=4;
00096 uchar c=(uchar)((val>>shift)&0xfU);
00097 if(c)
00098 { *dest++=hexdig[c]; break; }
00099 }
00100 while(shift)
00101 {
00102 shift-=4;
00103 *dest++=hexdig[(val>>shift)&0xfU];
00104 }
00105 } break;
00106 default: Assert(0);
00107 }
00108
00109 return(dest);
00110 }
00111
00112
00113 char *FastInt2String(char *dest,uint8 val,char base)
00114 { return(_UInt2String<uint8>(dest,val,base)); }
00115 char *FastInt2String(char *dest,uint16 val,char base)
00116 { return(_UInt2String<uint16>(dest,val,base)); }
00117 char *FastInt2String(char *dest,uint32 val,char base)
00118 { return(_UInt2String<uint32>(dest,val,base)); }
00119 char *FastInt2String(char *dest,uint64 val,char base)
00120 { return(_UInt2String<uint64>(dest,val,base)); }
00121
00122
00123 template<typename T,typename UT>static inline char *_SInt2String(
00124 char *dest,T val,char base)
00125 {
00126 UT uval;
00127
00128 if(val<0)
00129 { *dest++='-'; uval=(UT)(-val); }
00130 else
00131 { uval=(UT)val; }
00132
00133 return(_UInt2String<UT>(dest,uval,base));
00134 }
00135
00136
00137 char *FastInt2String(char *dest,int8 val,char base)
00138 { return(_SInt2String<int8,uint8>(dest,val,base)); }
00139 char *FastInt2String(char *dest,int16 val,char base)
00140 { return(_SInt2String<int16,uint16>(dest,val,base)); }
00141 char *FastInt2String(char *dest,int32 val,char base)
00142 { return(_SInt2String<int32,uint32>(dest,val,base)); }
00143 char *FastInt2String(char *dest,int64 val,char base)
00144 { return(_SInt2String<int64,uint64>(dest,val,base)); }
00145
00146
00147 template<typename T>static char *_Float2String(char *dest,T val)
00148 {
00149 if(val==0)
00150 { *dest++='0'; }
00151
00152 if(val<0)
00153 { *dest++='-'; val=-val; }
00154 *dest++='0';
00155 *dest++='x';
00156 *dest++='.';
00157
00158 int exp=0;
00159 val=NUM::frexp(val,&exp);
00160
00161
00162
00163
00164
00165
00166 static const int m_digs =
00167 sizeof(T)==8 ? 13 :
00168 sizeof(T)==4 ? 6 : 0;
00169
00170
00171 for(int i=0; i<m_digs; i++)
00172 {
00173 val*=16.0;
00174 int iv=(int)val;
00175 *dest++=hexdig[iv];
00176 val-=(T)iv;
00177 if(val==0.0) break;
00178 }
00179
00180
00181
00182
00183 *dest++='p';
00184
00185 dest=_SInt2String<int,uint>(dest,exp,10);
00186
00187 return(dest);
00188 }
00189
00190 char *FastFloat2String(char *dest,flt val)
00191 { return(_Float2String<flt>(dest,val)); }
00192 char *FastFloat2String(char *dest,dbl val)
00193 { return(_Float2String<dbl>(dest,val)); }
00194
00195
00196 #if 0
00197
00198
00199 #include <stdio.h>
00200
00201 int main()
00202 {
00203 char tmp[256];
00204
00205 char *s=tmp;
00206
00207
00208
00209
00210 s=FastFloat2String(s,0x.81201p0);
00211 *s='\0';
00212
00213 fprintf(stderr,"out=<%s>\n",tmp);
00214
00215 return(0);
00216 }
00217 #endif