题目:科学计数法
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].
[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。
现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。
输入格式:
每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。
输出格式:
对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。
输入样例 1:
+1.23400E-03
输出样例 1:
0.00123400
输入样例 2:
-1.2E+10
输出样例 2:
-12000000000
解题思路:
输入部分主要是由2部分组成,分别包括一个符号和一个数,我们可以利用char数组,将这些数据都保存到数组中,并按照下标依次来进行访问,我们可以设置一个变量where_E用来分割小数部分和倍数部分,然后可以将小数部分和倍数部分都从数组形式转换成浮点数形式num1和num2,最后再将这两个数相乘就可以得到最终的结果了。
求助:
在样例2的情况下,由于C++会在当数据过大的时候自动的将float型数据转换成科学计数法表示,所以无法得到正确的结果,我尝试用fixed,但是其会保留6位小数,也不符合答案。右图为C++的科学计数法表示结果,左图为使用fixed,但是会在小数点后保留6位有效数字。
注意:
①当小数部分末尾有0的时候,需要将0的个数记录下来,最后得到的数中是包含这个个0的有效位的。
代码:
#include<iostream>
#include<math.h>
#define MAX 10000
using namespace std;
int main()
{
char A[MAX]; //用于存储实数
cin>>A;
float num = 0.0f; //用于存储最终的答案
float num1 = 0.0f; //将A的小数部分的数组转换成小数
float num2 = 0.0f; //将A的倍数部分的数组转换成小数
int where_E = 0; //记录E在数组下标的何处
int i;
int not_0 = 0; //记录小数部分最后非0的下标(用于最后输出有效位)
//得到小数部分的A
num1 = (A[1]-48) * 1.0f; //整数部分
for(i=3;A[i] != 'E';i++) //小数部分
{
float x = (pow((float)10,-(int)(i-2)));
num1 += (A[i] - 48) * 1.0f * x;
if(A[i] != '0')
{
not_0 = i;
}
}
where_E = i; //得到E所在的位置
//得到倍数部分的A
for(i=i+2;A[i] != '\0';i++)
{
num2 = 10 * num2 + (A[i]-48);
}
//计算A
if(A[where_E+1] == '+') //变大
{
num = num1 * pow(10,+num2);
}
else if(A[where_E+1] == '-') //变小
{
num = num1 * pow(10,-num2);
}
//输出
if(A[0] == '-') //为负数
{
cout<<"-"; //输出负号
}
cout<<num;
for(int j=not_0;j<where_E-1;j++)
{
cout<<"0";
}
cout<<endl;
system("pause");
return 0;
}