大数的除法运算

数学里的除法运算通常写作:
y / x = a …b

如果写成等价的乘法形式,则是:
y = ax + b

这个式子有个性质,就是,如果用100x来代替式中的x, 分成2个式子
y = a1(100x) + y1
y1 = a2 x +b1

就有 a= a1a2的连缀, b= b1。这个性质可以用来分段计算a值。
如果用2进制,写成
y = a0a1a2…an x +b

移项得,
y - a0 (2^n *x) - … - an x = b
这是一个连续减的计算。 a0…an的取值是0或1。在连续减的过程,如果y >= 2^i x 相应的系数就取1,否则就取0。这样的a0a1…an连缀起来就是商a, 最后剩下的y就是余数b。

写成代码就是:

class big {
public:
        struct imp {
                struct  list {
                        unsigned int val;
                        struct list *prev;
                        struct list *next;
                };
                int n;
                list *numbers;
                list *rear;
                int link;

                imp& operator+=(imp &x);
                imp& operator-=(imp &x);
                imp& operator*=(imp &x);

                imp& divas(imp &x);
                imp& div(imp &x, imp &r);
                imp& div_debug(imp &x, imp &r);

                int cmp(imp& x);

                imp& operator+(imp &x);
                imp& operator-(imp &x);
                imp& operator*(imp &x);

                void del();
                void dup(imp &x);
                void free();
        };

        int sign;
        struct imp *data;

public:
        big(){sign=0;data=0;}
        big(int a[], int n);
        big(int num);
        big(const big &x);
        void neg() { if (data && data->n) sign = !sign; }

        ~big();
        big& operator=(const big &a);
        big& operator+=(const big& a);
        big& operator-=(const big& a);
        big& operator*=(const big& a);
        big& operator/=(const big& a);
        big& operator%=(const big& a);

        big operator+(const big& a);
        big operator-(const big& a);
        big operator*(const big& a);
        big operator/(const big& a);
        big operator%(const big& a);

        big div(const big& a, big &r);

        int tostring(char *s, int n);

        int toint();
        int cmp(const big &a);
        int operator>(const big &a) {return cmp(a)>0;}
        int operator<(const big &a) {return cmp(a)<0;}
        int operator==(const big &a) {return cmp(a)==0;}
        int operator>=(const big &a) {return cmp(a)>=0;}
        int operator<=(const big &a) {return cmp(a)<=0;}
        int operator!=(const big &a) {
                if (this==&a)return 0;
                if (!data || !a.data) return 1;
                return cmp(a)!=0;
        }
        big operator-() {big b; b= *this; b.neg(); return b; }
};


big::imp& big::imp::div(imp& x, imp &r)
{
        imp d;
        imp tab[TABLEN];
        int i;
        struct list *lp;
        struct list *node;
        struct list *cache;
        int ext;
        int sum;

        imp &s = *gethead();
        s.link=0;
        s.n =0;
        s.numbers= s.rear=0;

        d.numbers=0;
        d.dup(x);
        d.link=0;


        tab[0].numbers=0;
        tab[0].dup(d);
        for(i=1; i<TABLEN; i++) {
                d += d;
                tab[i].numbers=0;
                tab[i].dup(d);
        }

        d.del();
        ext=0;
        lp = numbers;
        while (d.n < x.n) {
        store_sd:
                if (s.n) {
                        node = getnode();
                        node->val =0;
                        node->next =0;
                        node->prev = s.rear;
                        s.rear->next = node;
                        s.rear = node;
                        ++s.n;
                }
                if (lp==0) goto done;
        store_d:
                node = getnode();
                node->val = lp->val;
                if (!d.numbers) {
                        d.rear= node;
                        node->prev=0;
                        node->next= 0;
                        d.numbers= node;
                }
                else {
                        node->prev = d.rear;
                        node->next = 0;
                        d.rear->next = node;
                        d.rear = node;
                }
                ++d.n;
                lp = lp->next;
        }
        if (ext==0) {
                switch (d.cmp(x)) {
                case 0:
                        d.del();
                        sum =1;
                        goto save;
                case -1:
                        ++ext;
                        goto store_sd;
                }
        }
        else ext=0;

        sum=0;
        for(i=TABLEN-1; i>=0; i--) {
                switch (d.cmp(tab[i])) {
                case 0:
                        sum += (1<<i);
                        d.del();
                        goto save;
                case 1:
                        d -= tab[i];
                        sum += (1<<i);
                        break;
                }
        }

save:
        node = getnode();
        node->val = sum;

        if (s.numbers) {
                node->prev = s.rear;
                node->next =0;
                s.rear->next = node;
                s.rear = node;
        }
        else {
                node->prev = node->next = 0;
                s.numbers= s.rear = node;
        }
        ++s.n;

        if (lp)  {
                if (d.n ==0 && lp->val==0) {
                        lp = lp->next;
                        sum = 0;
                        goto save;
                }
                goto store_d;
        }

done:
        for(i=0; i<TABLEN; i++) tab[i].del();
        r = d;
        return s;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,当我们对两个整数进行除法时,结果将是一个浮点数。但是,如果我们想要得到整数除法的结果,我们可以使用“//”运算符。此外,我们可以使用“%”运算符来获得余数。但是,当我们处理大数除法时,我们需要注意一些问题。 一种解决大数除法的方法是使用Python的Decimal模块。Decimal模块提供了高精度的十进制算术运算。我们可以使用Decimal模块中的divide()函数来执行大数除法。下面是一个示例代码: ```python from decimal import * a = Decimal('123456789012345678901234567890') b = Decimal('987654321098765432109876543210') c = a / b print(c) ``` 输出结果为: ``` 0.1249999999999999999999999999 ``` 另一种解决大数除法的方法是使用Python的long division算法。这种算法可以手动模拟除法过程,从而避免使用浮点数。下面是一个示例代码: ```python a = '123456789012345678901234567890' b = '987654321098765432109876543210' # 将字符串转换为数字列表 a = [int(x) for x in a] b = [int(x) for x in b] # 执行长除法 q = [] r = [] for d in a: r.append(d) s = 0 while len(r) >= len(b): t = b.copy() m = len(r) - len(t) t = [0] * m + t s += 1 for i in range(len(t)): r[i] -= t[i] if r[i] < 0: r[i] += 10 r[i+1] -= 1 while len(r) > 0 and r[-1] == 0: r.pop() q.append(s) # 将数字列表转换为字符串 q = ''.join([str(x) for x in q]) r = ''.join([str(x) for x in r]) print(q) print(r) ``` 输出结果为: ``` 0 123456789012345678901234567890 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值