• 9、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
     
    解题思路:这道题是求数的高精度幂,如果直接用double做,肯定会超出计算机可以表示的范围,所以初步的想法为用字符代替double,这样的话我们就需要细化求幂的过程。在进行运算之前,先将小数变为整数,在最后根据小数位数再还原为小数形式,所以可以简化为整数的幂运算。我用了四个函数:多位数乘一位数,多位数加多位数,多位数乘多位数,多位数的幂运算。多位数乘一位数和多位数加多位数为多位数乘多位数服务,多位数乘多位数为幂运算服务。所以大致过程为:输入底数和幂,判断底数是否含有小数点,若无,为整数,直接代入多位数的幂运算函数;若有小数点,求出小数位数,然后去掉小数点转换为整数,进行多位数的幂运算,计算之后先根据底数的小数位数和幂的大小确定结果的小数位数,讲小数点还原,之后再根据题目要求将多余的前置0和后置0去掉,输出结果。
     
    具体代码:
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 int flag, digit;
      5 char *longnumMulone(char *longChar, char one, int offset){
      6         int longLength=strlen(longChar);
      7         char *finalChar =(char*)malloc(sizeof(char)* 1000);
      8         int oneNum = one - 48;
      9         int i;
     10         for (i = 0; i < longLength + offset + 1; i++){
     11                 finalChar[i] = '0';
     12         }
     13         finalChar[longLength + offset + 1] = 0;
     14         int carryFlag,longNum,temp;
     15         carryFlag = 0;
     16         for (i = longLength-1; i >=0; i--){
     17                 longNum = longChar[i] - 48;
     18                 int temp = longNum*oneNum+carryFlag;
     19                 finalChar[i+1] = temp%10+48;
     20                 carryFlag = temp/10;
     21         }
     22         finalChar[0] = carryFlag + 48;
     23         return finalChar;
     24 }
     25 
     26 void longPlusLong(char *longChar1, char *longChar2){
     27         int length1 = strlen(longChar1);
     28         int length2 = strlen(longChar2);
     29         int longNum1, longNum2,temp1;
     30         int carry1 = 0;
     31         int i;
     32         for (i = 1; i <=length1; i++){
     33                 longNum1 = longChar1[length1 - i] - 48;
     34                 if (length2 < i){
     35                         longNum2=0;
     36                 }
     37                 else{
     38                         longNum2 = longChar2[length2 - i] - 48;
     39                 }
     40                 temp1 = longNum1 + longNum2 + carry1;
     41                 longChar1[length1 - i] = temp1 % 10 + 48;
     42                 carry1 = temp1 / 10;
     43         }
     44         free(longChar2);
     45 }
     46 
     47 char *longMullong(char *longChar1, char *longChar2){
     48         int l1, l2;
     49         l1 = strlen(longChar1);
     50         l2 = strlen(longChar2);
     51         int i;
     52         char *temp2 =(char*)malloc(sizeof(char)* 1000);;
     53         for (i = 0; i <l1+l2; i++){
     54                 temp2[i] = '0';
     55         }
     56         temp2[l1 + l2] = 0;
     57         char *temp3;
     58         for (i = 1; i<=l2; i++){
     59                 temp3 = longnumMulone(longChar1, longChar2[l2-i], i-1);
     60                 longPlusLong(temp2, temp3);
     61         }
     62         return temp2;
     63 }
     64 
     65 char *powerLong(char *longChar, int N){
     66         int length = strlen(longChar);
     67         char *finalChar = (char*)malloc(sizeof(char)* 1000);;
     68         int i;
     69         if (N < 2)
     70                 return longChar;
     71         for (i = 0; i <N*length; i++){
     72                 finalChar[i] = '0';
     73         }
     74         finalChar[N*length] = 0;
     75         finalChar = longMullong(longChar, longChar);
     76         for (i = 0; i < N - 2; i++){
     77                 finalChar = longMullong(finalChar, longChar);
     78         }
     79         return finalChar;
     80 }
     81 
     82 char *outputChar(char *afterChar,int N){
     83         int digit1 = digit*N;
     84         int length1 = strlen(afterChar);
     85         char *resultChar = (char*)malloc(sizeof(char)* 1000);
     86         if (flag == 1){
     87                 return afterChar;
     88         }
     89         else{
     90                 int i;
     91                 for (i = 0; i < length1 + 1; i++){
     92                         if (i == length1 - digit1)
     93                                 resultChar[i] = '.';
     94                         if (i<length1 - digit1)
     95                                 resultChar[i] = afterChar[i];
     96                         if (i>length1 - digit1)
     97                                 resultChar[i] = afterChar[i - 1];
     98                 }
     99                 resultChar[length1 + 1] = 0;
    100                 int j = -1;
    101                 while (resultChar[++j]== '0');
    102                 for (i = 0; i < length1 + 1 - j; i++){
    103                         resultChar[i] = resultChar[i+j];
    104                 }
    105                 resultChar[length1 + 1 - j] = 0;
    106                 int str = strlen(resultChar);
    107                 int k = str;
    108                 while (resultChar[--k]=='0');
    109                 if ((k + 1) != str){
    110                         resultChar[k + 1] = 0;
    111                         if (resultChar[k] == '.')
    112                                 resultChar[k] = 0;
    113                 }
    114         }
    115         return resultChar;
    116 }
    117 
    118 int main(){
    119         char input[20];
    120         char *output;
    121         int n;
    122         while (scanf("%s%d", input, &n) != EOF){
    123                 int length = strlen(input);
    124                 int i, j;
    125                 int location = -1;
    126                 for (i = 0; i < length; i++){
    127                         if (input[i] == '.')
    128                                 location = i;
    129                 }
    130                 if (location == -1)
    131                         flag = 1;
    132                 else
    133                         flag = 2;
    134                 if (location != -1){
    135                         digit = length - location - 1;
    136                         for (i = j = 0; input[i] != ''; i++){
    137                                 if (input[i] != '.')
    138                                         input[j++] = input[i];
    139                         }
    140                         input[j] = '';
    141                 }
    142                 output = outputChar(powerLong(input, n), n);
    143                 printf("%s
    ", output);
    144         }
    145         return 0;
    146 }
    做题感悟:1、在C语言中没有new,我们必须使用malloc函数 。C语言的malloc函数的使用方法:
    char *finalChar =(char*)malloc(sizeof(char)* 1000);
    也没有delete,使用free(finalChar)的形式来释放指针。
    2、我本来打算将输入底数的去小数点的部分也定义为一个函数,然后在主函数中直接调用即可,但是后来运行出现了异常。究其原因大概是用指针做形参。将变量地址(即本题中的数组名)作为实参、将指针做形参为值传递的方式,传递的是变量的地址,只能改变指针的值,不能改变相应的变量值;除非改变指针指向的变量的值的时候,相应的变量数值会发生变化,可以反应到实参。
    3、做题的时候无需考虑输入的数据的格式问题,OJ给的测试数据一定是严格按照题目要求的输入格式来的,如果在代码里再进行格式检查,没有必要且浪费时间(当然这是做题,自己做项目的时候,这方面就要考虑了)。
    4、在POJ上提交代码,如果C出现编译错误compiled error,使用GCC试一下,这个会比较宽松。
  • 相关阅读:
    oracle数据类型
    hive的union,hive连接查询的优化,mapjoin的设置参数
    hive分隔符
    hive load数据到表的方式
    hive的常用命令操作与数据类型以及hive的严格模式
    hadoop fs 与 dfs 的区别
    pl/sql程序语法,存储过程, orcle服务
    mysql连接启动
    HTTP协议
    php6
  • 原文地址:https://www.cnblogs.com/langzi1996/p/6440822.html
Copyright © 2020-2023  润新知