高精度加法,减法,乘法,除法

主要分为5个方面来开展:

1.高精度数的存储,我是按照《晴神宝典》的用一个包含int数组和表示长度int的struct bign来存储数据,当然了,为了方便,我们存储方向和我们正常的数字大小排列方向相反,我们是数组低位存放阶数小的数字,这样方便之后的计算

2.加法,加法应该就是直接模拟,记得用一个carry来存放进位就行了,其他的没有什么好说

2.减法,减法的话就是多了个向高处借位,既高一位的地方-1,自己位置+10,最后要消除前导0

4.乘法,乘法也是简单模拟,两个数的每一位和每一位相乘,然后再相加

5.除法,除法是最难的一个,虽然也是模拟,但是你使用高精度数除以一个高精度数的时候还是有点难度,首先整个模拟过程要清晰:

  输入的被除数a,除数b

  每一个循环的被除数=余数*10+当前位置数,用被除数除以除数(除数即为我们输入的除数b),如果

  (1)够除的话,那就得到商,和新的余数

  (2)如果不够除,就直接把被除数赋给余数

  进入下一个循环,直至a的位数都用完

  这里有一个技巧就是(1)中要怎么除,因为是高精度除以高精度,所以没办法使用内置除法,故此处使用减法来模拟除法(即不断地去减,直至减不了)

#include<iostream>
#include<stdio.h>
#include<string>
#include<cstring>
using namespace std;

const int max_size=1000;

struct bign{
    int d[max_size];
    int len;
    bign(){
        len=0;
        memset(d,0,sizeof(d));
    }
};

bign to_bign(string str){
    bign big;
    int size=str.size();
    big.len=size;
    for(int i=0;i!=size;++i)
        big.d[i]=str[size-1-i]-‘0‘;  //注意这里是string的char转化为int,要用-‘0‘变通一下
    return big;
}

bign add(bign a,bign b){
    bign c;
    int carry=0;
    for(int i=0;i<=a.len-1 || i<=b.len-1;++i){
        int temp=carry+a.d[i]+b.d[i];
        c.d[c.len++]=temp%10;
        carry=temp/10;
    }
    if(carry!=0){
        c.d[c.len++]=carry;
    }
    return c;
}

int cmp(bign a,bign b){
    int i;
    if(a.len>=b.len)
        i=a.len;
    else i=b.len;
    for(;i>=0;i--){
        if(a.d[i]>b.d[i]) return 1;
        else if(a.d[i]<b.d[i]) return -1;
    }
    return 0;
}

bign sub(bign a,bign b){ //a-b, 保证a>b
    bign c;
    for(int i=0;i<a.len;++i){  //a肯定是长的那一个
        if(a.d[i]-b.d[i]<0){
            a.d[i+1]--;
            a.d[i]+=10;
        }
        c.d[c.len++]=a.d[i]-b.d[i];
    }
    //消除前导0
    while(c.len-1>=1 && c.d[c.len-1]==0){
        c.len--;
    }
    return c;
}

bign multi(bign a,bign b){
    bign c;
    for(int i=0;i<a.len;++i){
        int m=a.d[i];
        for(int j=0;j<b.len;++j){
            int temp=c.d[i+j]+m*b.d[j];
            c.d[i+j]=temp%10;
            c.d[i+j+1]+=temp/10;
        }
    }
    if(c.d[a.len+b.len-1]!=0)
        c.len=a.len+b.len;
    else c.len=a.len+b.len-1;
    return c;
} 

//高精度除以高精度,好难写啊,原来我是卡在用减法模拟除法那里了
bign result_n;
bign remain_n;
bign division(bign a,bign b){ //a/b
    int bits=b.len;
    bign remain;
    bign sub1;
    string result_str;
    for(int i=a.len-1;i>=0;--i){
        remain=multi(remain,to_bign("10")); //余数*10
        string str;
        str+=(‘0‘+a.d[i]);
        sub1=add(remain,to_bign(str));
        int if_bigger=cmp(sub1,b);
        if(if_bigger>=0){
            //法模拟除法
            int count=0;
            while(cmp(sub1,b)>=0){
                sub1=sub(sub1,b);
                count++;
            }
            result_str+=(‘0‘+count); //存下商
            remain=sub1; //保留此次余数
        }
        else{
            remain=sub1;
        }
    }
    result_n=to_bign(result_str);
    remain_n=remain;
}

void print_bign(bign b){
    for(int i=b.len-1;i>=0;--i)
        printf("%d",b.d[i]);
}

int main(){
    freopen("in.txt","r",stdin);

    string str1,str2;
    cin>>str1>>str2;  //string对象的读写还是用cin>>string和cout<<string,不要用scanf,printf,不然有问题
    bign b1=to_bign(str1);
    bign b2=to_bign(str2);

    division(b1,b2);
    print_bign(result_n);
    printf("   ");
    print_bign(remain_n);

    return 0;
}

原文地址:https://www.cnblogs.com/chuan-chuan/p/11498452.html

时间: 2024-11-06 03:37:27

高精度加法,减法,乘法,除法的相关文章

高精度 加法 减法 乘法 除法 整合

此文为博主原创,转载时请通知博主,并把原文链接放在正文醒目位置. 很久不写高精了,虽说我觉得高精也不会考...还是稍微写一写,防止手生. 两个小时过去了…… 集合了高精+高精.高精-高精.高精*高精.高精/低精. 目前还没发现什么错误,应该可以应付各种情况. 本来想允许它读入负数的,结果发现减法读负数太麻烦了...所以只能读非负数. 下面贴代码. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #

BigDecimal 加法减法乘法除法

Java的简单类型不能够精确的对浮点数进行运算 /** * 提供精确的加法运算. * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); ret

加法 减法 乘法 除法计算

加法: function numAdd(num1, num2) {  var baseNum, baseNum1, baseNum2;  try {   baseNum1 = num1.toString().split(".")[1].length;  } catch (e) {   baseNum1 = 0;  }  try {   baseNum2 = num2.toString().split(".")[1].length;  } catch (e) {   

C语言(7)--高精度加法、减法、乘法、今天是星期几、四位平方数、候选人选票问题

1.高精度加法.减法.乘法 #include <stdio.h> #include <string.h> #include <malloc.h> void plus(char *a,char *b,char *c);//自定义高精度加法函数 void sub(char *a,char *b,char *c);//自定义高精度减法函数 void multiply(char *a,char *b,char *c);//自定义高精度乘法函数 int main() { char

Codevs高精度入门(减法、加法和乘法)解题报告

题目:                                                  题目描述 Description 给出两个正整数A和B,计算A-B的值.保证A和B的位数不超过500位. 输入描述 Input Description 读入两个用空格隔开的正整数 输出描述 Output Description 输出A-B的值 样例输入 Sample Input 3 12 样例输出 Sample Output -9 题目分析                          

[CareerCup] 7.4 Implement Multiply Subtract and Divide 实现乘法减法和除法

7.4 Write methods to implement the multiply, subtract, and divide operations for integers. Use only the add operator. 这道题让我们实现乘法加法和除法,而且规定了只能使用加法.那么我们先来看如何用加法来实现减法,我们知道,减去一个数就等于加上这个数的负数.那么我们先写一个求负数的函数,对于n来说,我们累计n个-1,对于-n来说,我们累计n个1.这样减法的就搞定了,我们再来看乘法,乘

一个基础而奇怪的问题:算法执行加法、乘法、除法性能无区别?

一个基础而奇怪的问题:算法执行加法.乘法.除法性能无区别? 计算机原理分析觉得:加法.乘法和除法的计算性能依次减少,但减少到什么程度? 编写C程序用30次百万数据计算来測试时间差异性,代码例如以下: #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000000 void add(float x[], long n) { float sum = 0; for(long i = 0; i

一个基础而奇怪的问题:算法运行加法、乘法、除法性能无差别?

一个基础而奇怪的问题:算法运行加法.乘法.除法性能无差别? 计算机原理分析认为:加法.乘法和除法的计算性能依次降低,但降低到什么程度? 编写C程序用30次百万数据计算来测试时间差异性,代码如下: #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000000 void add(float x[], long n) { float sum = 0; for(long i = 0; i &

9.7数学与概率(二)——实现整数的乘法、减法和除法运算,只允许使用加号

/** * 功能:实现整数的乘法.减法和除法运算.只允许使用加号. */ //减法 public static int minus(int a,int b){ return a+negate(b); } //取反 /** * 思路:对正数k的取反,只需要将-1连续加k次:对负数k的取反,只需要将1连续加k次. * @param a * @return */ public static int negate(int a){ int neg=0; int d=a>0?-1:1; while(a!=0