高精度数的四则运算+N!

来源:互联网 发布:古墓丽影崛起配置优化 编辑:程序博客网 时间:2024/06/06 12:57

//header.h

#include <iostream>

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


#define NN 20000
using namespace std;


/**
*
* @Author:  cc
* @Date:    Wed Dec 06 2017 16:18:37
*
* @simple dicri: 计算高精度数
* @full dicri:
*
**/


//计算位数
int CountIntBits(const int digit) {
  int s = 0, i = digit;
  while (0 != (i = (i / 10)))
    s++;
  return ++s;
}


//数字字符串转化为数字数组
void convert_s2i(int iNum[], string sNum) {
  int i = 0;
  memset(iNum, 0, sizeof(iNum));
  iNum[0] = sNum.length();


  if (iNum[0] == 0)
    return;
  for (i = 1; i <= iNum[0]; i++) {
    iNum[i] = sNum[iNum[0] - i] - '0';
  }
}


//高精度+高精度,iNum第一个元素为位数,低位在前,高位在后
void HPplusHP(int iNum[], char *a1, char *b1) {
  int a[NN] = {0}, b[NN] = {0};
  int i = 0, j = 0, k = 0;


  for (i = 0; i < strlen(a1); i++) {
    if (a1[i] - '0' < 0 || a1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (a1[i] - '0' != 0)
      j++;
  }
  if (j == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }
  k = 0;
  for (i = 0; i < strlen(b1); i++) {
    if (b1[i] - '0' < 0 || b1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (b1[i] - '0' != 0)
      k++;
  }
  if (j == 0 && k == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }


  a[0] = strlen(a1);          //第一个元素为位数
  for (i = 1; i <= a[0]; i++) //转为数字,低位在前,高位在后
    a[i] = a1[a[0] - i] - '0';


  b[0] = strlen(b1);          //第一个元素为位数
  for (i = 1; i <= b[0]; i++) //转为数字,低位在前,高位在后
    b[i] = b1[b[0] - i] - '0';


  k = a[0] > b[0] ? a[0] : b[0]; // k是a和b中位数最大的一个的位数
  for (i = 1; i <= k; i++) {
    iNum[i] += (a[i] + b[i]);
    iNum[i + 1] += (iNum[i] / 10); //若有进位,则先进位
    iNum[i] %= 10;
  }
  iNum[0] = 0;
  // m位+n位最多结果最多不会大于max(m,n)+1位
  for (i = k + 1; i >= 1 && iNum[i] == 0; i--)
    ;
  iNum[0] = i; // i--最后已经减去1,所以能再减1
}


//高精度-高精度,iNum第一个元素存位数,第二位存正负符号(0正,1负)
void HPminusHP(int iNum[], char *a1, char *b1) {
  int a[NN] = {0}, b[NN] = {0};
  int i = 0, j = 0, k = 0, tag = -1;


  for (i = 0; i < strlen(a1); i++) {
    if (a1[i] - '0' < 0 || a1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (a1[i] - '0' != 0)
      j++;
  }
  if (j == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }
  k = 0;
  for (i = 0; i < strlen(b1); i++) {
    if (b1[i] - '0' < 0 || b1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (b1[i] - '0' != 0)
      k++;
  }
  if (j == 0 && k == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }


  a[0] = strlen(a1);              //第一个元素为位数
  for (i = 2; i <= a[0] + 1; i++) //转为数字,低位在前,高位在后
    a[i] = a1[a[0] + 1 - i] - '0';
  for (i = a[0] + 2; i > 0 && a[i] == 0; i--)
    ;
  a[0] = i - 1;


  b[0] = strlen(b1);              //第一个元素为位数
  for (i = 2; i <= b[0] + 1; i++) //转为数字,低位在前,高位在后
    b[i] = b1[b[0] + 1 - i] - '0';
  for (i = b[0] + 2; i > 0 && b[i] == 0; i--)
    ;
  b[0] = i - 1;


  tag = -1;
  if (a[0] > b[0])
    tag = 0;
  else if (a[0] < b[0])
    tag = 1;
  else {
    //从最高位开始比较
    for (i = a[0]; i >= 2; i--) {
      if (a[i] > b[i]) {
        tag = 0;
      } else if (a[i] < b[i]) {
        tag = 1;
      } else
        continue;
    }
  }
  if (tag == -1)
    tag = 0;


  iNum[0] = 0;
  iNum[1] = tag;
  if (tag == 0) {
    for (i = 2; i < a[0] + 2; i++) {
      if (a[i] < b[i]) {
        a[i] = a[i] + 10 - b[i];
        a[i + 1] -= 1;
      } else {
        a[i] = a[i] - b[i];
      }
      iNum[i] = a[i];
    }
    // m位+n位最多结果最多不会大于max(m,n)+1位
    for (i = a[0] + 2 - 1; i >= 2 && iNum[i] == 0; i--)
      ;
    iNum[0] = i - 1; // i--最后已经减去1,所以再减1就可以
  } else {
    for (i = 2; i < b[0] + 2; i++) {
      if (b[i] < a[i]) {
        b[i] = b[i] + 10 - a[i];
        b[i + 1] -= 1;
      } else {
        k = b[i] - a[i];
        b[i] -= a[i];
      }
      iNum[i] = b[i];
    }
    // m位+n位最多结果最多不会大于max(m,n)+1位
    for (i = b[0] + 2 - 1; i >= 2 && iNum[i] == 0; i--)
      ;
    iNum[0] = i - 1; // i--最后已经减去1,所以再减1就可以
  }
}


//高精度x高精度,iNum第一个元素为位数,低位在前,高位在后
void HPmultiHP(int iNum[], char *a1, char *b1) {
  int a[NN] = {0}, b[NN] = {0};
  int i = 0, j = 0;


  for (i = 0; i < strlen(a1); i++) {
    if (a1[i] - '0' < 0 || a1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (a1[i] - '0' != 0)
      j++;
  }
  if (j == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }
  j = 0;
  for (i = 0; i < strlen(b1); i++) {
    if (b1[i] - '0' < 0 || b1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (b1[i] - '0' != 0)
      j++;
  }
  if (j == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }


  a[0] = strlen(a1);          //第一个元素为位数
  for (i = 1; i <= a[0]; i++) //转为数字,低位在前,高位在后
    a[i] = a1[a[0] - i] - '0';


  b[0] = strlen(b1);          //第一个元素为位数
  for (i = 1; i <= b[0]; i++) //转为数字,低位在前,高位在后
    b[i] = b1[b[0] - i] - '0';


  for (i = 1; i <= a[0]; i++) //竖式乘法
  {
    for (j = 1; j <= b[0]; j++) {
      iNum[i + j - 1] = iNum[i + j - 1] + a[i] * b[j];
      iNum[i + j] = iNum[i + j] + iNum[i + j - 1] / 10; //进位
      iNum[i + j - 1] = iNum[i + j - 1] % 10;           //进位后取余
    }
  }
  iNum[0] = 0;
  // m位×n位最多结果最多不会大于m+n位
  for (i = a[0] + b[0] + 1; i >= 1 && iNum[i] == 0; i--)
    ;
  iNum[0] = i; // i--最后已经减去1,所以能再减1
}


//高精度数字字符串*int,iNum第一个元素为位数,低位在前,高位在后
void HPmultiInt(int iNum[], char *a1, int b1) {
  int a[NN] = {0}, b[NN] = {0};
  int i = 0, j = 0;
  for (j = 0; j < NN; j++) {
    b[j] = 0;
    a[j] = 0;
  } //关键位置,避免脏数据


  for (i = 0; i < strlen(a1); i++) {
    if (a1[i] - '0' < 0 || a1[i] - '0' > 9) {
      printf("非数字字符串!");
      iNum[0] = 0;
      iNum[1] = 0;
      return /* code */;
    }
    if (a1[i] - '0' != 0)
      j++;
  }
  if (j == 0) {
    iNum[0] = 1;
    iNum[1] = 0;
    return /* code */;
  }


  a[0] = strlen(a1);          //第一个元素为位数
  for (i = 1; i <= a[0]; i++) //转为数字,低位在前,高位在后
    a[i] = a1[a[0] - i] - '0';


  // getIntBits(b,b1);
  i = 1;
  j = b1;
  while (0 != j) {
    b[i] = j % 10;
    j /= 10;
    i++;
    b[0]++;
  };


  for (i = 1; i <= a[0]; i++) //竖式乘法
  {
    for (j = 1; j <= b[0]; j++) {
      iNum[i + j - 1] = iNum[i + j - 1] + a[i] * b[j];
      iNum[i + j] = iNum[i + j] + iNum[i + j - 1] / 10; //进位
      iNum[i + j - 1] = iNum[i + j - 1] % 10;           //进位后取余
    }
  }
  iNum[0] = 0;
  // m位×n位最多结果最多不会大于m+n位
  for (i = a[0] + b[0] + 1; i >= 1 && iNum[i] == 0; i--)
    ;
  iNum[0] = i; // i--最后已经减去1,所以能再减1
}


// //高精度乘单精度数
// //a、res第0位是正(0)负号(-1),第1位是位数
// void  HPmultiInt2(int iRNum[], int a[], int it)
//{
// int i = 0, k = 0;
// for (i = 0; i < iRNum[1]; i++) iRNum[i] = -1; //初始化,避免脏数据
// for (i = 0; i < a[1] + 2;  i++) iRNum[i] = a[i];
// //for (i = 0; i < iRNum[1] + 2; i++) printf("%d ", iRNum[i]);
//
// //处理it=0情况
// if (it == 0) { iRNum[1] = 1;  iRNum[2] = 0;  return; }
// //处理正负情况
// if ((it < 0 && iRNum[0] < 0) || (it > 0 && iRNum[0] > 0)) iRNum[0] = 0;
// if ((it < 0 && iRNum[0] > 0) || (it > 0 && iRNum[0] < 0)) iRNum[0] = -1;
//
// int t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0;
//
// for (i = 2; i < iRNum[1] + 2; i++) iRNum[i] *= it; //先每位乘起来
// //printf("\n");
// //for (i = 2; i < iRNum[1] + 2; i++) printf("%d ", iRNum[i]);
//
// for (i = 2; i < iRNum[1] + 2; i++) {//对每位判断进位
// t1 = (iRNum[i] / 10);
// iRNum[i + 1] += (iRNum[i] / 10);
// t2 = iRNum[i + 1];
// iRNum[i] %= 10;
// t3 = iRNum[i];
// t4 = iRNum[1];
// if (i == iRNum[1] + 1 && iRNum[i + 1] > 0)
// iRNum[1]++;
// t5 = iRNum[1];
// }//此时i=iRNum[1]+1
//}


//高精度乘单精度数,单精度数是指通常的整型数
// a、iRNum第0位是位数
void HPmultiInt2_debug(int iRNum[], int a[], int it) {
  int i = 0, k = 0;
  for (i = 0; i < iRNum[0]; i++)
    iRNum[i] = -1; //初始化,避免脏数据
  for (i = 0; i < a[0] + 1; i++)
    iRNum[i] = a[i];


  printf("单独对每位相乘得:\n");
  for (i = 0; i < iRNum[0] + 1; i++) {
    printf("%d ", iRNum[i]);
    if (i == 0)
      printf("位:");
  }
  printf("\n");


  //处理it=0情况
  if (it == 0) {
    iRNum[0] = 1;
    iRNum[1] = 0;
    return;
  }
  for (i = 1; i < iRNum[0] + 1; i++)
    iRNum[i] *= it; //先每位乘起来


  printf("单独对每位乘 %d 得:\n", it);
  for (i = 1; i < iRNum[0] + 1; i++)
    printf("%d ", iRNum[i]);
  printf("\n");


  int t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0;
  for (i = 1; i < iRNum[0] + 1; i++) { //对每位判断进位
    t1 = (iRNum[i] / 10);
    iRNum[i + 1] += (iRNum[i] / 10);
    t2 = iRNum[i + 1];
    iRNum[i] %= 10;
    t3 = iRNum[i];
    t4 = iRNum[0];
    if (i == iRNum[0] && iRNum[i + 1] > 0)
      iRNum[0]++;
    t5 = iRNum[0];
  }
}


/////////////////////////////////////////////////
//////////////
/////////////////////////////////////////////////////


//取数位存入数组iNum:第0个元素是位数,之后是逆序数位
void i2iarray(int iNum[], const int it) {
  int imod = 0, i = 1;
  for (i = 0; i < NN; i++)
    iNum[i] = 0; //关键部分,避免脏数据
  imod = it;
  i = 1;
  while (0 != imod) {
    iNum[i] = imod % 10;
    imod /= 10;
    iNum[0]++;
    i++;
  };
}


//数字字符串转化为数字数组iNum
void c2iarray(int iNum[], const char *sNum) {
  int i = 0, j = 0;
  for (j = 0; j < NN; j++)
    iNum[j] = 0; //关键部分,避免脏数据
  iNum[0] = strlen(sNum);
  if (iNum[0] == 0)
    return;
  j = 0;
  for (i = 0; i < iNum[0]; i++) {
    if (sNum[i] - '0' < 0 || sNum[i] - '0' > 9) {
      printf("含有非数字字符!");
      return;
    }
    if (sNum[i] - '0' != 0)
      j++;
  }
  if (j > 0)
    for (i = 1; i <= iNum[0]; i++)
      iNum[i] = sNum[iNum[0] - i] - '0';
  else {
    iNum[0] = 0;
    iNum[1] = 0;
  }
}


//若iNum1>iNum2则为1,iNum1<iNum2则为-1,iNum1==iNum2则为0
int compare(int iNum1[], int iNum2[]) {
  int i = 0;
  if (iNum1[0] > iNum2[0])
    return 1;
  if (iNum1[0] < iNum2[0])
    return -1;


  for (i = iNum1[0]; i > 0; i--) { //从最高位开始比较
    if (iNum1[i] > iNum2[i])
      return 1;
    else if (iNum1[i] < iNum2[i])
      return -1;
    else
      continue;
  }
  return 0; //各位都相等
}


//高精度x单精度,iRNum,iNum,it第0个元素为位数,低位在前,高位在后
void HPmultiInt2(int iRNum[], int iNum[], int it) {
  int i = 0, k = 0;
  for (i = 0; i < iRNum[0]; i++)
    iRNum[i] = -1; //初始化,避免脏数据
  for (i = 0; i < iNum[0] + 1; i++)
    iRNum[i] = iNum[i];
  //处理it=0情况
  if (it == 0) {
    iRNum[0] = 1;
    iRNum[1] = 0;
    return;
  }
  for (i = 1; i < iRNum[0] + 1; i++)
    iRNum[i] *= it;                    //先每位乘起来
  for (i = 1; i < iRNum[0] + 1; i++) { //对每位判断进位
    iRNum[i + 1] += (iRNum[i] / 10);
    iRNum[i] %= 10;
    if (i == iRNum[0] && iRNum[i + 1] > 0)
      iRNum[0]++;
  }
}


//高精度x高精度,iRNum,iNum1,iNum2第0个元素为位数,低位在前,高位在后
void HPmultiHP2(int iRNum[], int iNum1[], int iNum2[]) {
  int i = 0, j = 0;
  for (j = 0; j < NN; j++)
    iRNum[j] = 0;                   //关键部分,避免脏数据
  for (i = 1; i <= iNum1[0]; i++) { //竖式乘法
    for (j = 1; j <= iNum2[0]; j++) {
      iRNum[i + j - 1] = iRNum[i + j - 1] + iNum1[i] * iNum2[j];
      iRNum[i + j] = iRNum[i + j] + iRNum[i + j - 1] / 10; //进位
      iRNum[i + j - 1] = iRNum[i + j - 1] % 10;            //进位后取余
    }
  }
  iRNum[0] = 0;
  // m位×n位最多结果最多不会大于m+n位
  for (i = iNum1[0] + iNum2[0] + 1; i >= 1 && iRNum[i] == 0; i--)
    ;
  iRNum[0] = i; // i--最后已经减去1,所以能再减1
}


//高精度+高精度,iNum第一个元素为位数,低位在前,高位在后
void HPplusHP2(int iRNum[], int iNum1[], int iNum2[]) {
  int i = 0, j = 0, k = 0;
  for (j = 0; j < NN; j++)
    iRNum[j] = 0; //关键部分,避免脏数据
  k = iNum1[0] > iNum2[0] ? iNum1[0] : iNum2[0]; //取位数最大的数的数位
  for (i = 1; i <= k; i++) {                     //竖式加法
    iRNum[i] += (iNum1[i] + iNum2[i]);
    iRNum[i + 1] += (iRNum[i] / 10); //若有进位,则先进位
    iRNum[i] %= 10;
  }
  iRNum[0] = 0;
  // m位+n位最多结果最多不会大于max(m,n)+1位
  for (i = k + 1; i >= 1 && iRNum[i] == 0; i--)
    ;
  iRNum[0] = i; // i--最后已经减去1,所以能再减1
}


//高精度-高精度,iRNum第一个元素存位数,tag = compare(iNum1, iNum2);
int HPminusHP2(int iRNum[], int iNum1[], int iNum2[], int tag) {
  int i = 0, j = 0, k = 0;
  for (j = 0; j < NN; j++)
    iRNum[j] = 0; //关键部分,避免脏数据


  iRNum[0] = 0;
  if (tag == 0) {
    iRNum[0] = 1;
    iRNum[1] = 0;
  } else if (tag == 1) {
    for (j = 0; j < iNum1[0] + 1; j++)
      iRNum[j] = iNum1[j];
    for (i = 1; i < iRNum[0] + 1; i++) {
      if (iRNum[i] < iNum2[i]) {
        iRNum[i] = iRNum[i] + 10 - iNum2[i];
        iRNum[i + 1] -= 1;
      } else
        iRNum[i] = iRNum[i] - iNum2[i];
    }
    for (i = iRNum[0]; i >= 1 && iRNum[i] == 0; i--)
      ;
    iRNum[0] = i;
  } else {
    for (j = 0; j < iNum2[0] + 1; j++)
      iRNum[j] = iNum2[j];
    for (i = 1; i < iRNum[0] + 1; i++) {
      if (iRNum[i] < iNum1[i]) {
        iRNum[i] = iRNum[i] + 10 - iNum1[i];
        iRNum[i + 1] -= 1;
      } else
        iRNum[i] = iRNum[i] - iNum1[i];
    }
    for (i = iRNum[0]; i >= 1 && iRNum[i] == 0; i--)
      ;
    iRNum[0] = i;
  }
  return tag;
}


//两个数组数字相乘
void multi(int iRNum[] /*结果*/, int imulti1[] /*被乘数*/,
           int imulti2[] /*乘数*/) {
  int i = 0, j = 0;
  for (j = 0; j < NN; j++)
    iRNum[j] = 0;                     //关键部分,避免脏数据
  for (i = 1; i <= imulti1[0]; i++) { //竖式乘法
    for (j = 1; j <= imulti2[0]; j++) {
      iRNum[i + j - 1] = iRNum[i + j - 1] + imulti1[i] * imulti2[j];
      iRNum[i + j] = iRNum[i + j] + iRNum[i + j - 1] / 10; //进位
      iRNum[i + j - 1] = iRNum[i + j - 1] % 10;            //进位后取余
    }
  }
  iRNum[0] = 0;
  // m位×n位最多结果最多不会大于m+n位
  for (i = imulti1[0] + imulti2[0] + 1; i >= 1 && iRNum[i] == 0; i--)
    ;
  iRNum[0] = i; // i--最后已经减去1,所以能再减1
}


//高精度数字数组 x int,ires、imulti第一个元素为位数,低位在前,高位在后
void HPArraymultiInt(int iRNum[], int imulti[], int ib) {
  int i = 0, j = 0;
  int b[NN] = {0};
  for (j = 0; j < NN; j++) {
    b[j] = 0;
    iRNum[j] = 0;
  } //关键位置,避免脏数据
  for (i = 1; i < imulti[0]; i++) {
    if (imulti[i] < 0 || imulti[i] > 9) {
      printf("非数字字符!");
      iRNum[0] = 0;
      iRNum[1] = 0;
      return /* code */;
    }
  }
  i = 1;
  j = ib;
  while (0 != j) {
    b[i] = j % 10;
    j /= 10;
    i++;
    b[0]++;
  };
  // multi(ires,imulti,b);
  for (i = 1; i <= imulti[0]; i++) //竖式乘法
  {
    for (j = 1; j <= b[0]; j++) {
      iRNum[i + j - 1] = iRNum[i + j - 1] + imulti[i] * b[j];
      iRNum[i + j] = iRNum[i + j] + iRNum[i + j - 1] / 10; //进位
      iRNum[i + j - 1] = iRNum[i + j - 1] % 10;            //进位后取余
    }
  }
  iRNum[0] = 0;
  // m位×n位最多结果最多不会大于m+n位
  for (i = imulti[0] + b[0] + 1; i >= 1 && iRNum[i] == 0; i--)
    ;
  iRNum[0] = i; // i--最后已经减去1,所以能再减1
}


//高精度N! 这个抄别人的,哈哈
//结果用数组a保存,开始时a[0] =1,依次乘以数组中各位,注意进位和数组长度的变化
void factorial(int a[], int *alen, int *flag /*当前位数*/, int n) {
  int i = 0, j = 0;
  memset(a, 0, sizeof(a));
  a[0] = 1, *flag = 1;
  for (j = 2; j <= n; j++) {


    // j分别数组a[i]上的每一位数字,并存入原数组对应的位置
    for (i = 0; i < *flag; i++)
      a[i] *= j;


    //对数组a[i]上的每一位数字,进行判断是否要进位
    for (i = 0; i < *flag; i++) {
      if (a[i] >= 10) {


        a[i + 1] += a[i] / 10;
        a[i] = a[i] % 10;


        //(*flag)是当前实际最大的位数,当i==*flag时,
        //说明位数flag必须要扩大1,才能容纳进位的数字;扩大之后进入一轮循环再判断,
        //若flag还是小,则还需再扩大flag
        if (i == *flag - 1)
          (*flag)++;
      }
    }
  }
  *alen = j;
}


//高精度N!
//结果用数组iRNum保存
void factorial2(int iRNum[], int n) {
  int j = 0;
  int swpRes[NN] = {0};
  int imulti[NN] = {0};
  memset(iRNum, 0, sizeof(iRNum));
  iRNum[0] = 1;
  iRNum[1] = 1;


  if (n < 2)
    return;
  else {
    for (int i = 2; i <= n; i++) {
      for (j = 0; j < NN; j++)
        imulti[j] = 0;
      for (j = 0; j < NN; j++)
        swpRes[j] = 0;
      i2iarray(imulti, i);
      multi(swpRes, iRNum, imulti);
      for (j = 0; j <= swpRes[0]; j++)
        iRNum[j] = swpRes[j];
    }
  }
}


//高精度N!
//结果用数组iRNum保存
void factorial3(int iRNum[], int n) {
  int i = 0, j = 0;
  iRNum[0] = 1, iRNum[1] = 1;
  int b[NN] = {0}, swpRes[NN] = {0};
  if (n < 2)
    return;
  else {
    for (int it = 2; it <= n; it++) {
      for (j = 0; j < NN; j++) {
        b[j] = 0;
        swpRes[j] = 0;
      } //关键位置,避免脏数据


      i = 1;
      j = it;
      while (0 != j) {
        b[i] = j % 10;
        j /= 10;
        b[0]++;
        i++;
      }; //把it转为数字数组b


      for (i = 1; i <= iRNum[0]; i++) { //竖式乘法
        for (j = 1; j <= b[0]; j++) {
          swpRes[i + j - 1] = swpRes[i + j - 1] + iRNum[i] * b[j];
          swpRes[i + j] = swpRes[i + j] + swpRes[i + j - 1] / 10; //进位
          swpRes[i + j - 1] = swpRes[i + j - 1] % 10; //进位后取余
        }
      }


      swpRes[0] = 0;
      for (i = iRNum[0] + b[0] + 1; i >= 1 && swpRes[i] == 0; i--)
        ;            // m位×n位,结果最多不会大于m+n位
      swpRes[0] = i; // i-- 最后已经减去1,所以能再减1
      for (j = 0; j <= swpRes[0]; j++)
        iRNum[j] = swpRes[j];
    }
  }
}


//高精度N!
//结果用数组iRNum保存
void factorial4(int iRNum[], int n) {
  int j = 0;
  int swpRes[NN] = {0};
  iRNum[0] = 1;
  iRNum[1] = 1;
  if (n < 2)
    return;
  else {
    for (int i = 2; i <= n; i++) {
      HPmultiInt2(swpRes, iRNum, i);
      for (j = 0; j <= swpRes[0]; j++)
        iRNum[j] = swpRes[j];
    }
  }

}

//xxx.cpp

// 高精度算法.cpp : 定义控制台应用程序的入口点。
//


#include "header.h"
 
int main(int argc, char const *argv[]) {


  //高精度-高精度
  // memset(iNum, 0, sizeof(iNum));
  // HPminusHP(iNum, a1, b1);
  // if (iNum[1]==1)
  //   printf("-");
  // for (i = iNum[0]+2-1; i >= 2; i--)
  //   printf("%d", iNum[i]);
  // printf("\n位数:%d\n\n", iNum[0]);


  //阶乘高精度运算
  // int flag = 0;
  // int alen = NN;
  // int nNum[NN] = { 0 };
  // memset(nNum, 0, sizeof(nNum));
  // factorial(nNum, &alen, &flag, 5);
  // printf("n!=");
  // for (alen = flag - 1; alen >= 0; alen--)
  // printf("%ld", nNum[alen]);


  //高精度-高精度
  int iNum[NN] = {0};
  int a[NN] = {0};
  int b[NN] = {0};
  /////////////////////////////////////////////////////////
  c2iarray(a, "1888");
  c2iarray(b, "77000"); //数字字符串转化为数字数组
  // i2iarray(iNum, 70);//int数字转化为数字数组
  // convert_s2i(iNum, "7467264716247000");//数字字符串转化为数字数组
  // printf("%d", CountIntBits(1));//计算整数中的数字个数
  //
  // int tag = compare(a, b); //比较两个数字数组的大小
  // if (tag == -1) printf("-");
  // HPminusHP2(iNum,a, b,tag); //2高精度-高精度
  // HPplusHP(iNum, "20", "1000");//高精度+高精度
  // HPplusHP2(iNum, a, b); //高精度+高精度
  // HPmultiHP(iNum, "20", "1000");//高精度数字字符串*数字字符串
  // HPmultiHP2(iNum, a, b); //高精度数字数组*数字数组
  // HPmultiInt(iNum, "1888", 23); //高精度数字字符串*int
  // HPmultiInt2(iNum, a, 5); //高精度数字数组*int, 可以高效处理N!运算
  // HPArraymultiInt(iNum, a, 23);//高精度数字数组*int
  // factorial3(iNum, 5000);////高精度N!
   factorial4(iNum, 5000);////高精度N!使用接口:HPmultiInt2
  //
  //
  /////////////////////////////////////////////////////////
  printf("计算结果:\n");
  for (int i = iNum[0]; i >= 1; i--)
    printf("%d", iNum[i]);
  printf("\n位数:%d\n\n", iNum[0]);


  return 0;
}


原创粉丝点击