dtostr,一个double to string,好纠结。

看看自己刚入门时写的东西!居然还用了一年!!要留下来,证明自己的成长。

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;
}

你可能感兴趣的:(dtostr,一个double to string,好纠结。)