1001. Exponentiation高精度运算总结

时间:2022-12-03 13:22:13
  • 解题思路

这道题属于高精度乘法运算,要求输入一个实数R一个指数N,求实数R的N次方,由于R有5个数位,而N又特别大,因此用C++自带的数据类型放不下.

解题思路是通过数组储存每次乘积结果和底数的每一位数,按照乘法上下算式的方法,计算底数乘数数组每一位与临时结果数组的每一位的乘积,(因为算术运算中是从数的后面往前算的,这里存储数时要先倒序,输出时再颠倒过来,)然后偏移相加,判断得出的临时结果数组的每一位是否大于9,通过除法和取模实现进位和取余.至此得出一个有很多无效数位的结果数组(很多无效的0).

最后判断结果数组的每一位是否为0,先输出小数点前面的数,后输出小数点后面的数,最终得出乘法结果.

这个题目实际上考的是高精度乘法,高精度的其他运算和这个差不多,原理都是一样的.

1001. Exponentiation高精度运算总结

  • Description

Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.

This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

  • Input

The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

  • Output

The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

  • Sample Input

95.123 12

0.4321 20

5.1234 15

6.7592 9

98.999 10

1.0100 12

  • Sample Output

548815620517731830194541.899025343415715973535967221869852721

.00000005148554641076956121994511276767154838481760200726351203835429763013462401

43992025569.928573701266488041146654993318703707511666295476720493953024

29448126.764121021618164430206909037173276672

90429072743629540498.107596019456651774561044010001

1.126825030131969720661201

  • Hint

If you don't know how to determine wheather encounted the end of input:

s is a string and n is an integer

  • SourceCode

#include<iostream>
#include<cstring> using namespace std; int main()
{
string r; //底数
int n,dianwei; //指数,小数点位置
const int len=200; //数位长度
short result[len],jieguo[len],chengshu[6]; //最终结果,临时结果,底数乘数
while(cin>>r>>n)
{
//初始化
for(int i=0;i<len;++i) jieguo[i]=result[i]=0;
for(int i=0;i<6;++i) chengshu[i]=0;
dianwei=0;
//得到底数小数点位置
size_t pos = r.find('.');
//如果底数中有小数点 获取小数点后面有多少位数
if(pos!=string::npos) dianwei=(5-pos)*n; //把底数中所有不是小数点的数字挑出来转换为int并赋给最终结果,临时结果,底数乘数 得到的是3个5位前后颠倒的数组 之所以颠倒是因为乘法是从后往前乘的
for(int i=5,j=0;i>=0;--i)
{
if(r[i]!='.')
{
jieguo[j]=result[j]=chengshu[j]=r[i]-'0';
++j;
}
} //当指数大于1时 进行以下运算 等于1时跳过这段程序直接输出
while(n>=2)
{
--n;
//初始化最终结果数组
for(int i=0;i<len;++i) result[i]=0; for(int i=0;i<5;++i) //从底数乘数的每一位
{
//底数乘数每位数和临时结果每位数相乘的临时变量
int temp;
for(int j=0;j<len;++j) //乘以临时结果的每一位
{
//如果底数乘数某一位是0 没必要乘下去了 跳出当前循环
if(chengshu[i]==0) break;
temp=chengshu[i]*jieguo[j];
//i+j实现乘法相加时的移位
result[i+j]+=temp;
//++t遍历所有结果数组中大于9的数 用除法和取模实现进位和余数
for(int t=i+j;result[t]>9;++t)
{
result[t+1]+=result[t]/10;
result[t]=result[t]%10;
}
}
}
//把一次乘法后的结果赋给临时结果来进行下次乘方
for(int i=0;i<len;++i) jieguo[i]=result[i];
} //获取最终结果从后数第一个不为0的数作为第一个数的标志位 之所以从后数 是因为之前颠倒的数要颠倒回来了
int firstindex=-1;
for(int i=len;i>=dianwei;--i)
{
if(result[i]>0)
{
firstindex=i;
break;
}
}
//获取 最终结果从前数第一个不为0的数作为最后一个数的标志位
int lastindex=-1;
for(int i=0;i<dianwei;++i)
{
if(result[i]>0)
{
lastindex=i;
break;
}
} //如果最终结果数组中不全是0 倒序输出结果数组中小数点前面的数
if(firstindex!=-1)
{
while(firstindex>=dianwei)
{
cout<<result[firstindex];
--firstindex;
}
}
//如果最终结果数组中不全是0 倒序输出结果数组中小数点后面的数
if(lastindex!=-1)
{
cout<<'.';
--dianwei;
while(dianwei>=lastindex)
{
cout<<result[dianwei];
--dianwei;
}
} cout<<endl;
}
}

附录:

一.高精度数的存储

1.字符串输入

#include <iostream>
#include <cstring>
using namespace std;
const int N=100;//最多100位
int main()
{
int a[N+1],i;
string s1;
cin>>s1;//数s1
memset(a,0,sizeof(a)); //数组清0
a[0]=s1.length(); //位数
for(i=1;i<=a[0];i++)
{
a[i]=s1[a[0]-i]-'0';//将字符转为数字并倒序存储.
}
return 0;
}

2.直接读入

#include <iostream>
using namespace std;
const int N=100;//最多100位
int main()
{
int a[N+1],i,s,key;
cin>>key;//数key
memset(a,0,sizeof(a)); //数组清0
i=0;//第0位
while(key) //当key大于0
{
a[++i]=key%10;//取第i位的数
key=key/10;
}
a[0]=i; //共i位数
return 0;
}

3.直接初始化(用a[]存储)

  • 初始化为0: memset(a,0,sizeof(a));
  • 初始化为1: memset(a,0,sizeof(a));a[0]=1;a[1]=1;

以下程序都只写函数,不写完整程序,所有高精度数存储都满足上述约定。

二.高精度数比较

int compare(int a[],int b[])   //比较a和b的大小关系,若a>b则为1,a<b则为-1,a=b则为0
{
int i;
if (a[0]>b[0]) return 1;//a的位数大于b则a比b大
if (a[0]<b[0]) return -1;//a的位数小于b则a比b小
for(i=a[0];i>0;i--) //从高位到低位比较
{
if (a[i]>b[i]) return 1;
if (a[i]<b[i]) return -1;
}
return 0;//各位都相等则两数相等。
}

三、高精度加法

int plus(int a[],int b[]) //计算a=a+b
{int i,k;
k=a[0]>b[0]?a[0]:b[0]; //k是a和b中位数最大的一个的位数
for(i=1;i<=k;i++)
{
a[i+1]+=(a[i]+b[i])/10; //若有进位,则先进位
a[i]=(a[i]+b[i])%10; //计算当前位数字,注意:这条语句与上一条不能交换。
}
if(a[k+1]>0)
{
a[0]=k+1; //修正新的a的位数(a+b最多只能的一个进位)
}
else
{
a[0]=k;
}
return 0;
}

四、高精度减法

int gminus(int a[],int b[]);//计算a=a-b,返加符号位0:正数 1:负数
{
int flag,i
flag=compare(a,b); //调用比较函数判断大小
if (falg==0)//相等
{
memset(a,0,sizeof(a));return 0; //若a=b,则a=0,也可在return前加一句a[0]=1,表示是 1位数0
}
if(flag==1) //大于
{
for(i=1;i<=a[0];i++)
{
if(a[i]<b[i]){ a[i+1]--;a[i]+=10;} //若不够减则向上借一位
a[i]=a[i]-b[i];
}
while(a[a[0]]==0) a[0]--; //修正a的位数
return 0;
}
if (flag==-1)//小于 则用a=b-a,返回-1
{
for(i=1;i<=b[0];i++)
{
if(b[i]<a[i]){ b[i+1]--;b[i]+=10; //若不够减则向上借一位
}
a[i]=b[i]-a[i];}
a[0]=b[0];
while(a[a[0]]==0) a[0]--; //修正a的位数
return -1;
}
}

五、高精度乘法(高精度乘单精度数,单精度数是指通常的整型数)

int multi1(int a[],long  key) //a=a*key,key是单精度数
{
int i,k;
if (key==0){memset(a,0,sizeof(a));a[0]=1;return 0;} //单独处理key=0
for(i=1;i<=a[0];i++)
{
a[i]=a[i]*key;//先每位乘起来
}
for(i=1;i<=a[0];i++)
{
a[i+1]+=a[i]/10;a[i]%=10; //进位
}
//注意上一语句退出时i=a[0]+1
while(a[i]>0)
{
a[i+1]=a[i]/10;a[i]=a[i]%10;i++;a[0]++]; //继续处理超过原a[0]位数的进位,修正a的位数
}
return 0;
}

1001. Exponentiation高精度运算总结的更多相关文章

  1. POJ 1001 Exponentiation&lpar;大数运算&rpar;

    POJ 1001 Exponentiation 时限:500 ms   内存限制:10000 K 提交材料共计: 179923   接受: 43369 描述:求得数R( 0.0 < R < ...

  2. 百炼1001&colon; Exponentiation 解题

    链接:http://bailian.openjudge.cn/practice/1001/ 思路 乍一看是很简单的题目,但是答案必须高精度输出,因此需要手动实现一个高精度运算方法.如果直接使用int, ...

  3. 高精度运算专题3-乘法运算(The multiplication operation)

    这个专题呢,我就来讲讲高精度的乘法,下面是三个计算乘法的函数,第一个函数是char类型的,要对字符串进行数字转换,而第二个是两个int类型的数组,不用转换成数字,第三个则更为优化,用a数组-b数组放回 ...

  4. &lbrack;code&rsqb;高精度运算

    数组存储整数,模拟手算进行四则运算 阶乘精确值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #includ ...

  5. 系统的讲解 - PHP 浮点数高精度运算

    目录 概述 浮点数运算的"锅" 任意精度数学函数 常用数值处理方案 扩展 小结 概述 记录下,工作中遇到的坑 ... 关于 PHP 浮点数运算,特别是金融行业.电子商务订单管理.数 ...

  6. &num;C&plus;&plus;初学记录&lpar;高精度运算&rpar;(加法)

    高精度运算 不管是int还是double亦或者long long ,这些定义变量都有数据范围的一定限制,在计算位数超过十几位的数,也就是超过他们自身的数据范围时,不能采用现有类型进行计算,只能自己通过 ...

  7. ICPC Asia Nanning 2017 F&period; The Chosen One &lpar;高精度运算&rpar;

    题目链接:The Chosen One 比赛链接:ICPC Asia Nanning 2017 题意 \(t\) 组样例,每组给出一个整数 \(n(2\le n\le 10^{50})\),求不大于 ...

  8. 算法模板 - C&plus;&plus; 高精度运算

    C++算法板子 高精度 高精度推荐用python来写,python有大整数,这里写的是关于C++的高精度运算模板 1.高精 * 低精 #include <iostream> #includ ...

  9. poj 1001 Exponentiation 第一题 高精度 乘方 难度&colon;1&lpar;非java&rpar;

    Exponentiation Time Limit: 500MS   Memory Limit: 10000K Total Submissions: 138526   Accepted: 33859 ...

随机推荐

  1. static成员变量与返回对象的引用

    (1)用static修饰类成员变量(属性),表明该变量是静态的,无论创建多少对象,都只创建一个一个静态属性副本,也就是对象们共享同一个静态属性,这个方法常用的一个用途就是用来计算程序调用了多少次这个类 ...

  2. 使用hexo&plus;github搭建免费个人博客详细教程

    [TOC] 本文目录(注意无法点击): 前言 体验更加排版请访问原文链接:http://blog.liuxianan.com/build-blog-website-by-hexo-github.htm ...

  3. Heritrix源码分析&lpar;十二&rpar; Heritrix的控制中心&lpar;大脑&rpar;CrawlController&lpar;一&rpar;&lpar;转)

    本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/650694 本博客已迁移到本人独立博客: http://www.yun5u.com/ ...

  4. IOS学习笔记1&grave;

    写了IOS的Hello World,记事本写的.除了一些基本的语法外,最主要的收获就是路径问题了. 直接把文件拖入终端,就会显示文件的完全限定名了.

  5. 解决 android&period;view&period;ViewGroup&dollar;LayoutParams cannot be cast to android&period;widget&period;AbsListView&dollar;LayoutParams

    错误日志1: 06-13 10:55:50.410: E/KVLog(1129): Error info:java.lang.ClassCastException: android.widget.Li ...

  6. C&num;操作Excel文件(转)

    摘要:本文介绍了Excel对象.C#中的受管代码和非受管代码,并介绍了COM组件在.net环境中的使用. 关键词:受管代码:非受管代码:Excel对象:动态连接库 引言 Excel是微软公司办公自动化 ...

  7. Pig系统分析&lpar;6&rpar;-从Physical Plan到MR Plan再到Hadoop Job

    从Physical Plan到Map-Reduce Plan 注:由于我们重点关注的是Pig On Spark针对RDD的运行计划,所以Pig物理运行计划之后的后端參考意义不大,这些部分主要分析流程, ...

  8. Linux Shell &colon; Test命令参数解析

    格式: test conditions test -n string : string 不为空 test -z string : string 为空 test int1 -eq int2  : int ...

  9. Postgres Linux 维护 随笔1(启动篇)

    关于postgres 起停操作随笔 Linux 环境下,对Postgres 起停常用代码 Postgres 启动 : pg_ctl start Postgres 停止 : pg_ctl stop Po ...

  10. 反射实现java深度克隆

    一.克隆 有时想得到对象的一个复制品,该复制品的实体是原对象实体的克隆.复制品实体的变化不会引起原对象实体发生变化,这样的复制品称为原对象实体的克隆对象或简称克隆. 1.浅复制(浅克隆) 概念:被复制 ...