uva784 Exponentiation (实数高精度乘方)

题意: 没什么好说的。 就是求实数的乘法。  注意点是: 输入的小数有后导零。 如最后一组1.0100  12 。 在输入的时候要判断。

思路: 记录小数位, 结果的小数位等于 一开始的小数位 * R。  用strchr()锁定小数点, 去掉小数点, 当整数去乘方。


第二次做这道题, 思路 条理都清楚了很多。


#include <cstdio>
#include <cstring>
using namespace std;

#define MAX_N 2000

void toDigitReverse(char *, int *);
void toPow(int *, int, int, int *rslt);
void outputRslt(int *, int);
void toMultiply(int *, int, int *, int);

int main()
{
	char strR[MAX_N];
	int n;
	char *radixP;
	int radixNum;
	int digitR[MAX_N];
	int lenR;
	int rslt[MAX_N];

	while (scanf("%s %d", strR, &n) == 2) {
		// init
		memset(digitR, 0, sizeof(digitR));
		memset(rslt, 0, sizeof(rslt));
		
		// count radix num
		int tp_len = strlen(strR);
		for (int i = tp_len - 1; strR[i] == '0'; i--) {
			strR[i] = '\0';
		}
		radixP = strchr(strR, '.');
		radixNum = strlen(radixP + 1);
		radixNum = radixNum * n;

		// delete radix
		*radixP = '\0';
		radixP++;
		if (strR[0] == '0') {			//0.xxx
			strcpy(strR, radixP);
		}else {
			strcat(strR, radixP);
		}
		lenR = strlen(strR);

		// to digit
		toDigitReverse(strR, digitR);

		// to pow
		toPow(digitR, lenR, n, rslt);

		// to output
		outputRslt(rslt, radixNum);

		// end a cases
	}

	return 0;
}

void toDigitReverse(char *strR, int *digitR)
{
	int len = strlen(strR);
	for (int head = 0, tail = len - 1; head < len; head++, tail--) {
		digitR[head] = strR[tail] - '0';
	}
}

void toPow(int *digitR, int lenR, int n, int *rslt)
{
	// rslt = digit at first
	for (int i = 0; i < lenR; i++) {
		rslt[i] = digitR[i];
	}
	n--;
	for (int i = 0; i < n; i++)	{
		toMultiply(rslt, MAX_N, digitR, lenR);	 // xx to be continue
	}
}

void outputRslt(int *rslt, int radixNum)
{
	int tail;
	for (tail = MAX_N - 1; !rslt[tail] && tail >= radixNum; tail--) {
	}

	radixNum--;				// index of rslt is from 0 1 2
	while (tail > radixNum) {
		printf("%d", rslt[tail--]);
	}
	printf(".");
	while (tail >= 0) {
		printf("%d", rslt[tail--]);
	}
	printf("\n");
}

void toMultiply(int *rslt, int lenRslt, int *digitR, int lenR)
{
	int tmp[MAX_N];
	memset(tmp, 0, sizeof(tmp));

	for (int i = 0;  i < lenRslt; i++) {
		for (int j = 0; j < lenR; j++) {
			tmp[i + j] += rslt[i] * digitR[j];
		}
	}

	int ans = 0;
	for (int i = 0; i < MAX_N; i++) {
		rslt[i] = (tmp[i] + ans) % 10;
		ans = (tmp[i] + ans) / 10;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值