浮点数字符串转换成浮点数实现(2)

        其实几年前实现过一个面试题版本的,参考:浮点数字符串转换成浮点数实现

        最近因为某些原因又拿了出来,做了一些简单的修改,支持了前端空格处理,溢出检测等等,当然精度处理这个难度有点大,没有特殊处理。另外带E(e)的浮点数字符串也进行了处理。需要特别说明的时候,运行时库里面是有一个类似的转换函数的,写一写只是练练手而已。

        头文件

/* -------------------------------------------------------------------------
//  文件名      :  KString2Float.h
//  创建者      :  magic
//  创建时间    :  2015/7/28 17:36:43
//  功能描述    :  
//
//  $Id: $
// -----------------------------------------------------------------------*/
#ifndef __KSTRING2FLOAT_H__
#define __KSTRING2FLOAT_H__

#include <float.h>
#include <windows.h>
// -------------------------------------------------------------------------
namespace NSUtil
{

// -------------------------------------------------------------------------
// 函数     : atofloat
// 功能     : 将一个字符串转换为浮点数
// 返回值   : float 
// 参数     : const char* s
// 附注     : 
// -------------------------------------------------------------------------
float atofloat(const char* s);

// -------------------------------------------------------------------------
// 函数     : wtofloat
// 功能     : 将一个宽字符串转换为浮点数
// 返回值   : float 
// 参数     : const wchar_t* s
// 附注     : 
// -------------------------------------------------------------------------
float wtofloat(const wchar_t* s);

// -------------------------------------------------------------------------
// 函数     : strtofloatT
// 功能     : 将一个字符串转换为浮点数
// 返回值   : float 
// 参数     : const tchar* s
// 附注     : 
// -------------------------------------------------------------------------
template<typename tchar>
float strtofloatT(const tchar* s)
{
    // check
    if (!s)
        return 0.0f;

    float fResult = 0.0f; // 存储结果
    tchar c = 0;

    // 整数部分
    bool bNegative = false;
    float fInteger = 0.0f;

    // 小数部分
    bool bDec = false;
    float fDecimal = 0.0f;
    float fDecPower = 0.1f;

    // 指数部分
    bool bMeetE = false;
    bool bEInFirst = true; // e不能在最前面
    bool bNegativeExponent = false;
    unsigned int nIntegerExponent = 0;
    float fExponentData = 1.0f;

    c = *s++;
    /* skip whitespace */
    while (0x20 == c)
        c = *s++;

    // 进行首位判断,判断是否是负数
    if (0x2d == c)
    {
        bNegative = true;
        c = *s++;
    }
    else if (0x2b == c)
    {
        bNegative = false;
        c = *s++;
    }

    while (0 != c)
    {
        if (bMeetE)
        {
            // 指数部分
            if (c >= 0x30 && c <= 0x39)
            {
                nIntegerExponent = nIntegerExponent * 10 + c - 0x30;
            }
            else
            {
                break;
            }
        }
        else
        {
            if (0x65 == c || 0x45 == c)
            {
                if (bEInFirst)
                    break;

                // 确定指数的符号
                c = *s;
                if (0 == c)
                    break;
                if (0x2d == c)
                {
                    bNegativeExponent = true;
                    c = *s++;
                }
                else if (0x2b == c)
                {
                    bNegativeExponent = false;
                    c = *s++;
                }

                bMeetE = true;
            }
            else if (bDec)
            {
                bEInFirst = false;
                // 小数部分
                if (c >= 0x30 && c <= 0x39)
                {
                    fDecimal += (c - 0x30) * fDecPower;
                    fDecPower = fDecPower * 0.1f;
                }
                else
                {
                    break;
                }
            }
            else
            {
                bEInFirst = false;
                // 整数部分
                if (c >= 0x30 && c <= 0x39)
                {
                    fInteger = fInteger * 10.0f + c - 0x30;
                }
                else if (c == 0x2e)
                {
                    bDec = true;
                }
                else
                {
                    break;
                }
            }
        }

        c = *s++;
    }

    // 指数处理
    if (bMeetE)
    {
        float fExponent = bNegativeExponent ? 0.1f : 10.0f;
        while (nIntegerExponent > 0)
        {
            fExponentData *= fExponent;
            --nIntegerExponent;
        }
    }

    // 溢出检测
    fResult = (bNegative? -(fInteger +  fDecimal) : fInteger + fDecimal);
    fResult *= fExponentData;
    if (fResult > FLT_MAX)
    {
        fResult = FLT_MAX;
    }
    else if (fResult < -FLT_MAX)
    {
        fResult = -FLT_MAX;
    }
    else if (fResult > 0 && fResult < FLT_MIN)
    {
        fResult = FLT_MIN;
    }
    else if (fResult < 0 && fResult > -FLT_MIN)
    {
        fResult = -FLT_MIN;
    }

    return fResult;
}

#if defined(UNICODE) || defined(_UNICODE)
    #define strtofloat  wtofloat
#else
    #define strtofloat  atofloat
#endif // !UNICODE

} // end NSUtil
// -------------------------------------------------------------------------
// $Log: $

#endif /* __KSTRING2FLOAT_H__ */


        实现代码

/* -------------------------------------------------------------------------
//  文件名      :  KString2Float.cpp
//  创建者      :  magic
//  创建时间    :  2015/7/28 17:36:48
//  功能描述    :  
//
//  $Id: $
// -----------------------------------------------------------------------*/

#include "stdafx.h"
#include "KString2Float.h"

// -------------------------------------------------------------------------
namespace NSUtil
{

// -------------------------------------------------------------------------
// 函数     : atofloat
// 功能     : 将一个字符串转换为浮点数
// 返回值   : float 
// 参数     : const char* s
// 附注     : 
// -------------------------------------------------------------------------
float atofloat(const char* s)
{
    // check
    if (!s)
        return 0.0f;

    float fResult = 0.0f; // 存储结果
    char c = 0;
    
    // 整数部分
    bool bNegative = false;
    float fInteger = 0.0f;

    // 小数部分
    bool bDec = false;
    float fDecimal = 0.0f;
    float fDecPower = 0.1f;
    
    // 指数部分
    bool bMeetE = false;
    bool bEInFirst = true; // e不能在最前面
    bool bNegativeExponent = false;
    unsigned int nIntegerExponent = 0;
    float fExponentData = 1.0f;

    c = *s++;
    /* skip whitespace */
    while (' ' == c)
        c = *s++;

    // 进行首位判断,判断是否是负数
    if ('-' == c)
    {
        bNegative = true;
        c = *s++;
    }
    else if ('+' == c)
    {
        bNegative = false;
        c = *s++;
    }

    while ('\0' != c)
    {
        if (bMeetE)
        {
            // 指数部分
            if (c >= '0' && c <= '9')
            {
                nIntegerExponent = nIntegerExponent * 10 + c - '0';
            }
            else
            {
                break;
            }
        }
        else
        {
            if ('e' == c || 'E' == c)
            {
                if (bEInFirst)
                    break;

                // 确定指数的符号
                c = *s;
                if ('\0' == c)
                    break;
                if ('-' == c)
                {
                    bNegativeExponent = true;
                    c = *s++;
                }
                else if ('+' == c)
                {
                    bNegativeExponent = false;
                    c = *s++;
                }

                bMeetE = true;
            }
            else if (bDec)
            {
                bEInFirst = false;
                // 小数部分
                if (c >= '0' && c <= '9')
                {
                    fDecimal += (c - '0') * fDecPower;
                    fDecPower = fDecPower * 0.1f;
                }
                else
                {
                    break;
                }
            }
            else
            {
                bEInFirst = false;
                // 整数部分
                if (c >= '0' && c <= '9')
                {
                    fInteger = fInteger * 10.0f + c - '0';
                }
                else if (c == '.')
                {
                    bDec = true;
                }
                else
                {
                    break;
                }
            }
        }

        c = *s++;
    }

    // 指数处理
    if (bMeetE)
    {
        float fExponent = bNegativeExponent ? 0.1f : 10.0f;
        while (nIntegerExponent > 0)
        {
            fExponentData *= fExponent;
            --nIntegerExponent;
        }
    }

    // 溢出检测
    fResult = (bNegative? -(fInteger +  fDecimal) : fInteger + fDecimal);
    fResult *= fExponentData;
    if (fResult > FLT_MAX)
    {
        fResult = FLT_MAX;
    }
    else if (fResult < -FLT_MAX)
    {
        fResult = -FLT_MAX;
    }
    else if (fResult > 0 && fResult < FLT_MIN)
    {
        fResult = FLT_MIN;
    }
    else if (fResult < 0 && fResult > -FLT_MIN)
    {
        fResult = -FLT_MIN;
    }
    
    return fResult;
}

// -------------------------------------------------------------------------
// 函数     : wtofloat
// 功能     : 将一个宽字符串转换为浮点数
// 返回值   : float 
// 参数     : const wchar_t* s
// 附注     : 
// -------------------------------------------------------------------------
float wtofloat(const wchar_t* s)
{
    // check
    if (!s)
        return 0.0f;

    float fResult = 0.0f; // 存储结果
    wchar_t c = 0;

    // 整数部分
    bool bNegative = false;
    float fInteger = 0.0f;

    // 小数部分
    bool bDec = false;
    float fDecimal = 0.0f;
    float fDecPower = 0.1f;

    // 指数部分
    bool bMeetE = false;
    bool bEInFirst = true; // e不能在最前面
    bool bNegativeExponent = false;
    unsigned int nIntegerExponent = 0;
    float fExponentData = 1.0f;

    c = *s++;
    while (L' ' == c)
        c = *s++;       /* skip whitespace */

    // 进行首位判断,判断是否是负数
    if (L'-' == c)
    {
        bNegative = true;
        c = *s++;
    }
    else if (L'+' == c)
    {
        bNegative = false;
        c = *s++;
    }

    while (L'\0' != c)
    {
        if (bMeetE)
        {
            // 指数部分
            if (c >= '0' && c <= '9')
            {
                nIntegerExponent = nIntegerExponent * 10 + c - '0';
            }
            else
            {
                break;
            }
        }
        else
        {
            if ('e' == c || 'E' == c)
            {
                if (bEInFirst)
                    break;

                // 确定指数的符号
                c = *s;
                if ('\0' == c)
                    break;
                if ('-' == c)
                {
                    bNegativeExponent = true;
                    c = *s++;
                }
                else if ('+' == c)
                {
                    bNegativeExponent = false;
                    c = *s++;
                }

                bMeetE = true;
            }
            else if (bDec)
            {
                bEInFirst = false;
                // 小数
                if (c >= L'0' && c <= L'9')
                {
                    fDecimal += (c - L'0') * fDecPower;
                    fDecPower = fDecPower * 0.1f;
                }
                else
                {
                    return (bNegative? -(fInteger +  fDecimal): fInteger + fDecimal);
                }
            }
            else
            {
                bEInFirst = false;
                // 整数
                if (c >= L'0' && c <= L'9')
                {
                    fInteger = fInteger * 10.0f + c - L'0';
                }
                else if (c == L'.')
                {
                    bDec = true;
                }
                else
                {
                    return (bNegative? -fInteger : fInteger);
                }
            }
        }
        c = *s++;
    }

    // 指数处理
    if (bMeetE)
    {
        float fExponent = bNegativeExponent ? 0.1f : 10.0f;
        while (nIntegerExponent > 0)
        {
            fExponentData *= fExponent;
            --nIntegerExponent;
        }
    }

    // 溢出检测
    fResult = (bNegative? -(fInteger +  fDecimal) : fInteger + fDecimal);
    fResult *= fExponentData;
    if (fResult > FLT_MAX)
    {
        fResult = FLT_MAX;
    }
    else if (fResult < -FLT_MAX)
    {
        fResult = -FLT_MAX;
    }
    else if (fResult > 0 && fResult < FLT_MIN)
    {
        fResult = FLT_MIN;
    }
    else if (fResult < 0 && fResult > -FLT_MIN)
    {
        fResult = -FLT_MIN;
    }

    return fResult;
}

} // end NSUtil
// -------------------------------------------------------------------------
// $Log: $

        测试代码

    float fffa = .0e-2;
    fffa = 0e-2;
    fffa = 1e-2;
    fffa = 1e+1;
    fffa = .1;
    float ffff = atof("-545444.5e-10.67f");
    ffff = atof("1e-10f");
    ffff = atof("1e-");
    ffff = atof("1e+");
    ffff = atof("1e0");



    float aaaa = NSUtil::atofloat("12.34");
    aaaa = NSUtil::atofloat("1e-10f");
    aaaa = NSUtil::atofloat("-545444.5e-10.67f");
    aaaa = NSUtil::atofloat("1e-");
    aaaa = NSUtil::atofloat("1e+");
    aaaa = NSUtil::atofloat("1E+");
    aaaa = NSUtil::atofloat("1e0");

    aaaa = NSUtil::atofloat("-545444.5e-10");
    aaaa = NSUtil::atofloat("-0.00000545444.5");
    aaaa = NSUtil::atofloat("-54544444444444444444444444444444444444.5");
    aaaa = NSUtil::atofloat("+1.345");
    aaaa = NSUtil::atofloat("   -34.00001");
    aaaa = NSUtil::atofloat("   -12.01001   ");
    aaaa = NSUtil::atofloat("  0.33344");
    aaaa = NSUtil::atofloat("a23");
    aaaa = NSUtil::atofloat("1234");
    aaaa = NSUtil::atofloat("12.34");
    aaaa = NSUtil::atofloat("12.34.56");
    aaaa = NSUtil::atofloat(".34");
    aaaa = NSUtil::atofloat("34a");
    aaaa = NSUtil::atofloat("34a.456");
    aaaa = NSUtil::atofloat("-34");
    aaaa = NSUtil::atofloat("-56.34");
    aaaa = NSUtil::atofloat("-3.45.67");
    aaaa = NSUtil::atofloat("-.45.6a");
    aaaa = NSUtil::atofloat("-.");
    aaaa = NSUtil::atofloat("-0");
    aaaa = NSUtil::atofloat("3.402823467e+38F");
    aaaa = NSUtil::atofloat("-54544444444444444444444444444444444444.5");
    aaaa = NSUtil::atofloat("5454444445444444444444444444444444444444.5");
    aaaa = NSUtil::atofloat("0.0000000000000000000000000000000000000001");
    aaaa = NSUtil::atofloat("-0.0000000000000000000000000000000000000001");

    aaaa = NSUtil::strtofloatT("1e-10f");
    aaaa = NSUtil::strtofloatT("-545444.5e-10.67f");
    aaaa = NSUtil::strtofloatT("1e-");
    aaaa = NSUtil::strtofloatT("1e+");
    aaaa = NSUtil::strtofloatT("1e0");
    aaaa = NSUtil::strtofloatT("+1.345");
    aaaa = NSUtil::strtofloatT("   -34.00001");
    aaaa = NSUtil::strtofloatT("   -12.01001   ");

    aaaa = NSUtil::strtofloatT(L"1e-10f");
    aaaa = NSUtil::strtofloatT(L"-545444.5e-10.67f");
    aaaa = NSUtil::strtofloatT(L"1e-");
    aaaa = NSUtil::strtofloatT(L"1e+");
    aaaa = NSUtil::strtofloatT(L"1e0");
    aaaa = NSUtil::strtofloatT(L"+1.345");
    aaaa = NSUtil::strtofloatT(L"   -34.00001");
    aaaa = NSUtil::strtofloatT(L"   -12.01001   ");

    aaaa = NSUtil::wtofloat(L"1e-10f");
    aaaa = NSUtil::wtofloat(L"-545444.5e-10.67f");
    aaaa = NSUtil::wtofloat(L"1e-");
    aaaa = NSUtil::wtofloat(L"1e+");
    aaaa = NSUtil::wtofloat(L"1e0");
    aaaa = NSUtil::wtofloat(L"+1.345");
    aaaa = NSUtil::wtofloat(L"   -34.00001");
    aaaa = NSUtil::wtofloat(L"   -12.01001   ");
    aaaa = NSUtil::wtofloat(L"  0.33344");
    aaaa = NSUtil::wtofloat(L"a23");
    aaaa = NSUtil::wtofloat(L"1234");
    aaaa = NSUtil::wtofloat(L"12.34");
    aaaa = NSUtil::wtofloat(L"12.34.56");
    aaaa = NSUtil::wtofloat(L".34");
    aaaa = NSUtil::wtofloat(L"34a");
    aaaa = NSUtil::wtofloat(L"34a.456");
    aaaa = NSUtil::wtofloat(L"-34");
    aaaa = NSUtil::wtofloat(L"-56.34");
    aaaa = NSUtil::wtofloat(L"-3.45.67");
    aaaa = NSUtil::wtofloat(L"-.45.6a");
    aaaa = NSUtil::wtofloat(L"-.");
    aaaa = NSUtil::wtofloat(L"-0");




tongji.gif

猜你喜欢

转载自blog.csdn.net/magictong/article/details/47111993