c++ 科学记数法string转double
转载自https://blog.****.net/jjj19891128/article/details/23679267
bool ParseNumber(const char* s,double* d)
{
bool bNegtiveBase,bNegtiveExp;//分别表示基数和指数是否为负
int nPreZero = 0;//基数前缀0的个数
const char* p;
int sum_i = 0;
double sum_f = 0.0;
int sum_exp = 0;
double sum = 0.0;
bNegtiveBase = bNegtiveExp = false;
if(!s)
return false;
if('-' == *s)
{
bNegtiveBase = true;
s++;
}
for(;'0' == *s;nPreZero++,s++);//统计基数前缀0的个数
for(;*s != '.' && *s != 'e' && *s != 'E' && *s != '\0';s++)
{
if(*s < '0' || *s > '9')
{
return false;
}
sum_i = sum_i*10 + *s - '0';
}
if(0 == sum_i && 0 == nPreZero)//基数为0且前缀0个数为0,说明是.25、e7、E7、“”之类的数据格式
return false;
if('.' == *s)//还需要计算小数部分数值
{
for(p = s;*p != 'e' && *p != 'E' && *p != '\0';p++);//找到尾数部分的末尾
if(s==p-1)
return false;
s = p;
p--;
for(;*p != '.';p--)
{
if(*p < '0' || *p > '9')
return false;
sum_f = sum_f*0.1 + 0.1*(*p - '0');
}
}
if('e' == *s || 'E' == *s)//还需要计算阶码
{
s++;
if('-' == *s)
{
bNegtiveExp = true;
s++;
}
else if('+' == *s)
{
bNegtiveExp = false;
s++;
}
nPreZero = 0;
for(;*s != '\0';s++)
{
if(*s < '0' || *s > '9')
{
return false;
}
sum_exp = sum_exp*10 + *s - '0';
nPreZero++;
}
if(0 == sum_exp && 0 == nPreZero)
return false;
}
sum = sum_i + sum_f;
if(bNegtiveExp)//阶码为负
{
while(sum_exp > 0)
{
sum /= 10;
sum_exp--;
}
}
else
{
while(sum_exp > 0)
{
sum *= 10;
sum_exp--;
}
}
if(bNegtiveBase)//基数为负
sum = -sum;
*d = sum;
return true;
}
对算法进行测试:
//测试函数
#include <iostream>
using namespace std;
int main()
{
double d = 0.0;
char* s[] = {"123562.578e56",
"-1254.0256e+23",
"-1254.0256e-23",
"1458921",
"14875.236",
"1423e-089",
"01546.3e-9",
"0000.000",
"000.000e000",
"00.01e+0",
".32",
"0.",
"0.e-7",
"0.2e",
"0.2e-6g",
"2a5.3e-6",
"2a5.3f6",
NULL};
for(int i=0;i<18;i++)
{
if(!ParseNumber(s[i],&d))
{
if(!s[i])
cout<<"指针为NULL"<<endl;
else
cout<<s[i]<<"非法"<<endl;
}
else
{
cout<<"\""<<s[i]<<"\""<<"="<<d<<endl;
}
}
return 0;
}