您的位置:首页 > 其它

精确乘幂

2015-12-20 21:37 218 查看

1. 算法思想

精确乘幂的思想秉承于大数乘法,但其实质仍是大数的相乘。只不过,由于底数可以为小数,相比较于大数相乘,需要处理小数点的问题。但是我们可以将采用分离的思想,记录小数点所在的位数(从右往左数,且从0开始)并去除小数点,先将小数换为大数,求出大数的成绩,再填入小数点。

2. 问题描述

2.1 问题描述

对一个实数R(R为0~1000之间的实数),编写程序精确计算R的N次方,其中N是整数且0<=N<=25.

2.2 输入

输入R和N,用空格分隔。

2.3 输出

R的N次方精确值,输出无需去掉无用的0,如果输出结果为整数,不要输出小数点。

3. 问题要点

在本题中,需要把握的要点有三点:

1)一个n位的整数和一个m位的整数相乘的结果,其位数最高为m+n;

2)两数相乘之后的小数点问题,可以迁移为:小数点位于第i位(从右往左数,且i从0开始,i=0代表该数为整数),相当于将小数点向左移动了i位。

那么,两个小数a和b相乘,a和b的小数点在第i,j位,那么处理完之后的结果中,小数点位于i+j位;

3)处理最终结果中无效的零,包括整数部分的0和小数部分的0.

4. 算法实现

4.1 重要函数声明

大数相乘算法声明

//大数相乘
//乘数:numsA,numsB
//长度:lenA, lenB
int BigNumberMultiplication(int * numsA, int lenA, int * numsB, int lenB, int *
results);


字符串向int转换函数实现

//change the string to the big-int and save them in array
//返回值:小数点的位数
//src: the String
//number: the array
//length: string's length
int string2int(char * src, int * number, int length);


4.2 算法完整实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//change the string to the big-int and save them in array //返回值:小数点的位数 //src: the String //number: the array //length: string's length int string2int(char * src, int * number, int length);
int string2int(char * src, int * number, int length)
{
int flag=0;
//define the buffer to store the data
char * str = (char *)malloc(sizeof(char)*(length+1));
memset(str, '\0', length+1);
memcpy(str, src, length);
/* puts(str);*/
strrev(str);
/* puts(str);*/
//transfer string to int
//int temp = *number; //原有的数据不为零时,也需要考虑
int i, j;
for (i=0, j=0; i<length; i++)
{
//temp *= 10;
//原有数据为字符'A',顾需要减去'0'
if (str[i]!='.')
{
number[j++] += (int)(str[i] - '0');
}
else
{
flag = j;
}

}
//return the transfer number
//*number = temp;
//clear the dynamic memory
free(str);
str = NULL;
return flag;
}

//大数相乘 //乘数:numsA,numsB //长度:lenA, lenB int BigNumberMultiplication(int * numsA, int lenA, int * numsB, int lenB, int * results);
int BigNumberMultiplication(int * numsA, int lenA, int * numsB, int lenB, int * results)
{
int i, j;
//multi procedure
for (i=0; i<lenB; i++)
{
for (j=0; j<lenA; j++)
{
//the i,j place number multi, and the result is on the i+j place
results[i+j] += numsA[j] * numsB[i];
}
}
//process the result
for (i=0; (i<lenA+lenB); i++)
{
if (results[i]>=10) //the low place to the high place, if the low number is >=
10
{
results[i+1] += results[i] /10;
results[i] %= 10;
}
}
//calcute lenA
for (i=lenA+lenB-1; i>=0; i--)
{
if (results[i] != 0)
{
break;
}
}
return i+1;
}

int main()
{
char str[7] = {'\0'};
int numsB[5] = {0};
int n;
scanf("%s %d", str, &n);
int length = strlen(str);
//获取小数点的位数
int PointPlace = string2int(str, numsB, length);
if (PointPlace!=0) // reduce the . nums
{
length--;
}

int * pNumsA = (int *)malloc(length*n*sizeof(int));
int * pResults = (int *)malloc(length*n*sizeof(int));
memset(pNumsA, 0, length*n*sizeof(int));
memset(pResults, 0, length*n*sizeof(int));
memcpy(pNumsA, numsB, length*sizeof(int));
// int i;
// for (i=0; i<length; i++)
// {
// printf("%d", pNumsA[i]);
// }
// printf("-%d\n", PointPlace);
int lenA = length;
/*printf("%d", lenA);*/
int i, j;
int bIsBegin = 0;
char * pString = (char *)malloc(sizeof(char)*length*n+2);
memset(pString, '\0', sizeof(char)*length*n+2);
if (n==1)
{
printf("%s", str);
}
else
{
//求幂
for (i=1; i<n; i++)
{
lenA = BigNumberMultiplication(pNumsA, lenA, numsB, length,
pResults);
memcpy(pNumsA, pResults, lenA*sizeof(int));
memset(pResults, 0, lenA*sizeof(int));
//printf("LenA---%d\n", lenA);
}

//将结果由数组转化为字符串并添加小数点
i=0;
j = 0;
while (i<length*n)
{
if (pNumsA[i]==0)
{
if (1==bIsBegin)
{
if ( i==(PointPlace*n) )
{
if (i!=0)
pString[j++] = '.';
}
pString[j++] = pNumsA[i++] + '0';
}
else
i++;

}
else
{
bIsBegin = 1; ////begin from the first non-zero value

if ( i==(PointPlace*n) )
{
if (i!=0)
{
pString[j++] = '.';
}

}

pString[j++] = pNumsA[i++] + '0';
}
}

free(pNumsA);
free(pResults);
//反转字符串:之前的字符串一直是倒叙的
strrev(pString);

//输出结果:主要是处理小数点前0的个数
if (PointPlace==0)
{
for (i=0; i<length*n; i++)
{
if (pString[i]!='0')
break;
}
printf("%s", &pString[i]);
}
else
{
for (i=0; i<length*n; i++)
{
if (pString[i]!='0')
{
if (pString[i]=='.')
{
i--;
break;
}
else
{
break;
}

}

}
printf("%s", &pString[i]);
}
}

free(pString);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: