PAT 乙级 1024(求助,如何取消float的自动科学计数法表示)

题目:科学计数法

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值