看看自己刚入门时写的东西!居然还用了一年!!要留下来,证明自己的成长。
char * tr_dtostr(double value, int declen)
{
char * pstring = NULL;
int64_t intval = 0;
uint16_t effenum = 0;
uint16_t renum = 0;
uint32_t i = 0;
int64_t longnum = 0;
uint64_t plongnum = 0;
int64_t anum = 0;
int64_t bnum = 0;
//有效位长度如果<0 或 >19位则等于19位
if (declen <= 0 || declen > 19)
{
declen = 19;
}
pstring = (char *) malloc(21);
memset(pstring, 0, 21);
intval = (int64_t) value;//获取整数值
if (value < 0.0)//确定负值
{
if (intval == 0)//确定整数位为0
{
char chnum[21] = {
0
};
sprintf(pstring, "%s", "-");
sprintf(chnum, "%lld", intval);
strcat(pstring, chnum);
strcat(pstring, ".");//存入“-0.”
}
else//整数位不为0存入“负数.”
{
sprintf(pstring, "%lld", intval);
strcat(pstring, ".");
}
if (intval != 0)//如果
{
renum = strlen(pstring) - 2;
}
else
{
renum = strlen(pstring) - 3;
}
effenum = 15 - renum;
}
else
{
sprintf(pstring, "%lld", intval);
strcat(pstring, ".");
if (intval != 0)
{
renum = strlen(pstring) - 1;
}
else
{
renum = strlen(pstring) - 2;
}
effenum = 15 - renum;
}
if (intval == 0)
{
anum = (value) * pow(10,effenum);
bnum = intval * pow(10,effenum);
longnum = anum - bnum;
plongnum = labs(longnum);
if (value > 0.0)
{
anum = (value + 1) * pow(10,effenum);
}
else if (value < 0.0)
{
anum = (value - 1) * pow(10,effenum);
}
else if (value == 0)
{
sprintf(pstring, "%s", "0");
return pstring;
}
}
else
{
anum = value * pow(10,effenum);
bnum = intval * pow(10,effenum);
longnum = anum - bnum;
plongnum = labs(longnum);
}
if (plongnum == 0)
{
//小数部位全为0
pstring[strlen(pstring)-1] = 0;
return pstring;
}
else
{
char chnum[20] = {
0
};
uint8_t sursavelen = 0;//剩余应该保存个数
int invallen = 0;//小数部位转为整数后的大小
int vallen = 0; //小数部位非零数的个数(包括非零数中间0的个数)
int tailzerolen = 0;//小数部位转为整数后尾部补的0的个数
int index = 0;
uint32_t frontzeronum = 0;//小数部位紧跟在小数点后有效0的个数
sursavelen = declen; // 剩余应保存个数初始值为需保留小数个数
for (index = 0;; index++)
{
uint64_t div = 0;
uint64_t rem = 0;
uint64_t squ = 0;
squ = pow(10, index + 1);
div = plongnum / squ;
rem = plongnum % squ;
if (rem == 0)//余数为0,尾零个数+1
{
tailzerolen++;
}
if (div >= 1)//除数>= 1, 整数个数+1
{
invallen++;
}
else
{
invallen += 1;//加上第一位
break;
}
}
vallen = invallen - tailzerolen;
//计算小数部位紧跟在小数点后有几个0
for (index = 0;; index++)
{
uint64_t temnum;
uint64_t div;
uint64_t squ = pow(10, invallen + index);
temnum = labs(anum) % squ;
div = labs(anum) / squ;
if (temnum == plongnum && div == intval)
{
break;
}
else if (temnum == plongnum)
{
frontzeronum++;
}
else
{
frontzeronum--;
break;
}
}
//将紧跟在小数点后的前0写入字符串
for (i = 0; i < frontzeronum; i++)
{
strcat(pstring, "0");
if (sursavelen > 0)
{
sursavelen--;//剩余应保留个数-1
}
}
if (sursavelen > vallen)
{
sursavelen = vallen;
}
if (sursavelen == 0)
{
uint8_t len = strlen(pstring);
if (intval == 0)
{
for (i = 0; i < len; i++)
{
pstring[len - i - 1] = 0;
}
pstring[0] = '0';
}
else
{
for (i = 0; i < frontzeronum + 1; i++)
{
pstring[len - 1 - i] = 0;
}
}
}
else
{
sprintf(chnum, "%lld", plongnum);//将小数点后数转换为字符串
strncat(pstring, chnum, sursavelen);
}
}
return pstring;
}