poj_1001 高精度浮点

本文介绍了一种使用C++实现的大数乘法和浮点数幂运算的方法,详细展示了如何处理包含小数点的字符串形式的大数,并通过乘法递归实现了高效的幂运算。文章还讨论了多种特殊情况的处理,如0次幂的情况和测试数据中可能出现的前导0问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嘈点太多。。。4个小时。。。

注意点:

(1)、0次幂=1;

(2)、测试数据有前导0;

(3)、0.001 -> .001

更多的测试数据看discuss,过了那些就AC了。。。


code:

<span style="font-size:18px;">#include <iostream>
#include <string>
#include <fstream>

using namespace std;

const int size = 1000;
char a[size + 1];
char ans[size*size + 1];

int frac, loc, n, max;

void mul(char a[], char b[], char ans[])
{
	int i, j, k;
	int A[size + 1] = { 0 };
	int B[size + 1] = { 0 };
	int ANS[size*size + 1] = { 0 };
	//char数组转换成int数组
	int lena = strlen(a);
	int lenb = strlen(b);
	for (int i = 0; i < lena; i++)
		A[i] = a[i] - '0';
	for (int i = 0; i < lenb; i++)
		B[i] = b[i] - '0';
	//相乘
	for (i = 0; i < lena; i++)
		for (j = 0; j < lenb; j++)
			ANS[i + j] += A[i] * B[j];
	for (i = 0; i < lena + lenb; i++)
	{
		ANS[i + 1] += ANS[i] / 10;
		ANS[i] = ANS[i] % 10;
	}
	int maxLen;
	for (i = size*size; i >= 0; i--)
	{
		if (ANS[i] != 0)
		{
			maxLen = i;
			break;
		}
	}
	//给ans重新赋值
	memset(ans, '\0', sizeof(ans));
	for (i = 0; i <= maxLen; i++)
	{
		ans[i] = ANS[i] + '0';
	}
	/*
	for (i = 0; i < lena; i++)
	{
	cout << A[i];
	}
	cout << endl;
	for (i = 0; i < lena+lenb ; i++)
	{
	cout << ANS[i];
	}
	cout << endl;
	*/
}

void reverse(char a[])
{
	char temp;
	int len = strlen(a);
	for (int i = 0; i < len / 2; i++)
	{
		temp = a[i];
		a[i] = a[len - 1 - i];
		a[len - 1 - i] = temp;
	}
}

void calDotLocation(char a[], int n)
{
	int len = strlen(a);
	bool has = false;
	for (int i = 0; i < len; i++)
	{
		if (a[i] == '.')
		{
			has = true;
			loc = i;
			break;
		}
	}
	if (has == false)
	{
		loc = -1;//如果没有小数点,loc=-1, frac=-1
		frac = -1;//小数点位置
		return;
	}
	frac = loc*n;
}

void delDot(char a[])
{
	if (loc == -1)
		return;
	int len = strlen(a);
	for (int i = loc; i < len; i++)
	{
		a[i] = a[i + 1];
	}
	a[len - 1] = '\0';
}

void assignValue(char a[], char ans[])
{
	int len = strlen(a);
	for (int i = 0; i < len; i++)
	{
		ans[i] = a[i];
	}
}

void insertDot()
{
	int i, j, k;
	int len = strlen(ans);
	if (frac == -1)
		return;
	else if (frac < len) //小数位数小于ans长度,在ans内部插入小数点
	{
		for (i = len; i >= len - frac; i--)
		{
			ans[i] = ans[i - 1];
		}
		ans[len - frac] = '.';
		ans[len + 1] = '\0';
	}
	else //小数位数大于等于ans长度,在ans前面恰当位置插入小数点 
	{
		char temp[size*size + 1];
		memset(temp, '\0', sizeof(temp));
		strcpy(temp, ans);
		ans[0] = '.';
		for (i = 0; i<frac - len; i++)  //补充0  
			ans[i + 1] = '0';
		for (j = i, k = 0; k<len; k++, j++)
			ans[j + 1] = temp[k];
		ans[j+1] = '\0';
	}
}

void delEndDotZero()
{
	if (frac == -1)
		return;
	int len = strlen(ans);
	int pa = len - 1;
	while (ans[pa] == '0')
		ans[pa--] = '\0';
	if (ans[pa] == '.')   //小数全为0  
		ans[pa--] = '\0';
}


void delStartDotZero()
{
	int i,pa = 0;
	while (ans[pa] == '0')  //寻找ans开头第一个不为0的位置  
		pa++;

	if (ans[pa] == '\0')  //没有小数  
	{
		ans[0] = '0';
		ans[1] = '\0';
	}
	else  //有小数  
	{
		for (i = 0; ans[pa] != '\0'; i++, pa++)
			ans[i] = ans[pa];
		ans[i] = '\0';
	}
}
int main()
{
	fstream in("input.txt");
	while (cin >> a >> n)
	{
		memset(ans, '\0', sizeof(ans));
		if (n == 0) // 任意数的0次幂=1
		{
			cout << 1 << endl;
			continue;
		}
		//反转
		reverse(a);
		//计算小数点位置
		calDotLocation(a, n);
		//去掉小数点
		delDot(a);
		//给ans赋初值a
		assignValue(a, ans);
		//乘法
		for (int i = 0; i < n - 1; i++)
		{
			mul(a, ans, ans);
		}
		//倒序,得到没有小数点的ans
		reverse(ans);
		//插入小数点
		insertDot();
		//删除ans小数末尾的0
		delEndDotZero();
		//删除ans整数开头的0,但至少保留1个0
		delStartDotZero();
		//output
		cout << ans << endl;
	}
	//system("pause");
	return 0;
}
</span>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值