首页 > 其他分享 >高精度 加减乘, 除法只提供商

高精度 加减乘, 除法只提供商

时间:2024-11-14 17:00:35浏览次数:1  
标签:digits bignum int 加减 lastdigit signbit PLUS 提供商 除法

// bigNum.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <cstring>

using namespace std;

#define MAXDIGITS   100110
#define PLUS        1
#define MINUS       -1

typedef struct {
    char digits[MAXDIGITS];
    int signbit;
    int lastdigit;
}bignum;

void initialize_bignum(bignum* c) {
    memset(c, 0, sizeof(bignum));
    c->signbit = PLUS;
}
void print_bignum(const bignum* const n) {
    int i;
    if (n->signbit == MINUS) printf("-");
    for (i = n->lastdigit; i >= 0; i--)
        printf("%c", '0' + n->digits[i]);
    printf("\n");
}

void zero_justify(bignum* n) {
    while ((n->lastdigit > 0) && (n->digits[n->lastdigit] == 0))
        n->lastdigit--;
    if ((n->lastdigit == 0) && (n->digits[0] == 0))
        n->signbit = PLUS;
}

int compare_bignum(bignum* a, bignum* b) {
    int i;

    if ((a->signbit == MINUS) && (b->signbit == PLUS)) return PLUS;
    if ((a->signbit == PLUS) && (b->signbit == MINUS)) return MINUS;

    if ((b->lastdigit > a->lastdigit)) return (PLUS * a->signbit);
    if ((a->lastdigit > b->lastdigit)) return (MINUS * a->signbit);

    for (i = a->lastdigit; i >= 0; i--) {
        if (a->digits[i] > b->digits[i])
            return (MINUS * a->signbit);
        if (b->digits[i] > a->digits[i])
            return (PLUS * a->signbit);
    }

    return 0;
}

void add_bignum(bignum* a, bignum* b, bignum* c);
void subtract_bignum(bignum* a, bignum* b, bignum* c) {
    int borrow;
    int v; int i;

    if ((a->signbit == MINUS) || (b->signbit == MINUS)) {
        b->signbit = -1 * b->signbit;
        add_bignum(a, b, c);
        b->signbit = -1 * b->signbit;
        return;
    }
    if (compare_bignum(a, b) == PLUS) {
        subtract_bignum(b, a, c);
        c->signbit = MINUS;
        return;
    }
    c->lastdigit = max(a->lastdigit, b->lastdigit);
    borrow = 0;

    for (i = 0; i <= (c->lastdigit); i++) {
        v = (a->digits[i] - borrow - b->digits[i]);
        if (a->digits[i] > 0)
            borrow = 0;
        if (v < 0) {
            v = v + 10;
            borrow = 1;
        }
        c->digits[i] = (char)v % 10;
    }
    zero_justify(c);
}




void add_bignum(bignum* a, bignum* b, bignum* c) {
    int carry;
    int i;

    initialize_bignum(c);

    if (a->signbit == b->signbit) c->signbit = a->signbit;
    else {
        if (a->signbit == MINUS) {
            a->signbit = PLUS;
            subtract_bignum(b, a, c);
            a->signbit = MINUS;
        }
        else {
            b->signbit = PLUS;
            subtract_bignum(a, b, c);
            b->signbit = MINUS;
        }
        return;
    }

    c->lastdigit = max(a->lastdigit, b->lastdigit) + 1;
    carry = 0;

    for (i = 0; i <= (c->lastdigit); i++) {
        c->digits[i] = (char)
            (carry + a->digits[i] + b->digits[i]) % 10;
        carry = (carry + a->digits[i] + b->digits[i]) / 10;
    }

    zero_justify(c);
}

void digit_shift(bignum* n, int d) {
    int i;
    if ((n->lastdigit == 0) && (n->digits[0] == 0)) return;

    for (i = n->lastdigit; i >= 0; i--)
        n->digits[i + d] = n->digits[i];

    for (i = 0; i < d; i++) n->digits[i] = 0;

    n->lastdigit = n->lastdigit + d;
}

void multiply_bignum(bignum* a, bignum* b, bignum* c) {
    bignum row;
    bignum tmp;
    int i, j;
    initialize_bignum(c);

    row = *a;

    for (i = 0; i <= b->lastdigit; i++) {
        for (j = 1; j <= b->digits[i]; j++) {
            add_bignum(c, &row, &tmp);
            *c = tmp;
        }
        digit_shift(&row, 1);
    }

    c->signbit = a->signbit * b->signbit;
    zero_justify(c);
}

void divide_bignum(bignum* a, bignum* b, bignum* c) {
    bignum row;
    bignum tmp;
    int asign, bsign;
    int i;  // j;

    initialize_bignum(c);

    asign = a->signbit;
    bsign = b->signbit;

    a->signbit = PLUS;
    b->signbit = PLUS;

    initialize_bignum(&row);
    initialize_bignum(&tmp);

    c->lastdigit = a->lastdigit;

    for (i = a->lastdigit; i >= 0; i--) {
        digit_shift(&row, 1);
        row.digits[0] = a->digits[i];
        c->digits[i] = 0;
        while (compare_bignum(&row, b) != PLUS) {
            c->digits[i]++;
            subtract_bignum(&row, b, &tmp);
            row = tmp;
        }
    }

    zero_justify(c);

    a->signbit = asign;
    b->signbit = bsign;
}

void int_to_bignum(int s, bignum* n) {
    int i;
    int t;
    if (s >= 0) n->signbit = PLUS;
    else n->signbit = MINUS;

    for (i = 0; i < MAXDIGITS; i++) n->digits[i] = (char)0;

    n->lastdigit = -1;

    t = abs(s);

    while (t > 0) {
        n->lastdigit++;
        n->digits[n->lastdigit] = (t % 10);
        t = t / 10;
    }
    if (s == 0) n->lastdigit = 0;
}


void string_to_bignum(string s, bignum* n) {
    int i;
    int t;
    if (s.size() >= MAXDIGITS) return;
    if (s[0] == '-') n->signbit = MINUS;
    else n->signbit = PLUS;

    for (i = 0; i < MAXDIGITS; i++) n->digits[i] = (char)0;
    n->lastdigit = -1;

    if (s[0] == '-' || s[0] == '+') s.erase(s.begin());

    int len = s.size()-1;
    for (; len >= 0; len--) {
        n->lastdigit++;
        n->digits[n->lastdigit] = s[len]-'0';
    }

    if(s=="0")n->lastdigit = 0;

    return;
}



int main()
{
    string sa, sb;
    cin >> sa >> sb;

    bignum a, b, c;
    string_to_bignum(sa, &a);
    string_to_bignum(sb, &b);
    //int_to_bignum(2,&a);
    //int_to_bignum(1, &b);
    divide_bignum(&a, &b, &c);
    print_bignum(&c);

    return 0;
}

 

标签:digits,bignum,int,加减,lastdigit,signbit,PLUS,提供商,除法
From: https://www.cnblogs.com/itdef/p/18546378

相关文章

  • 什么是 ISP:了解互联网服务提供商的作用
    一、ISP基础知识从本质上讲,ISP提供两项主要服务:互联网接入和互联网传输。互联网接入是指使用户能够连接到互联网的物理和逻辑连接,通常通过调制解调器、路由器或其他网络设备。此连接可以是有线的(例如通过DSL、光纤或电缆)或无线的(例如蜂窝数据或卫星)。另一方面,互联网传输涉......
  • 什么是 ISP:了解互联网服务提供商的作用
    一、ISP基础知识从本质上讲,ISP提供两项主要服务:互联网接入和互联网传输。互联网接入是指使用户能够连接到互联网的物理和逻辑连接,通常通过调制解调器、路由器或其他网络设备。此连接可以是有线的(例如通过DSL、光纤或电缆)或无线的(例如蜂窝数据或卫星)。另一方面,互联网传输涉......
  • 《高精度除法》
    【题目描述】输入一个高精度数,一个低精度数(int),然后求高精度数除以低精度数的商和余数并输出。【样例输入】223344556677892【样例输出】111672278338941#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;intt;cin>>s;cin>>t;inta[......
  • 模二除法详解
    模二除法(Modulo-2Division)是一种特殊的除法运算,用于计算二进制数据的CRC校验码。这种运算与普通的除法类似,但区别在于它使用不进位的异或运算来代替普通除法中的减法操作。模二除法的结果为二进制余数,应用在校验过程中以检验数据完整性。模二除法的基本规则模二除法的每一......
  • 带进位加减指令(ADC)和加法指令(ADD)作用上有什么区别
    带进位加减指令(ADC)和加法指令(ADD)作用上的区别:1.CarryFlag的使用;2.适用情景的区别;3.循环进位的处理;4.数据的精度要求;5.标志位的设置;6.性能差异。ADC指令是带有进位标志(CarryFlag)的加法指令,ADD指令执行简单的加法操作,不考虑之前的进位。1.CarryFlag的使用ADC指令:ADC......
  • AWS和Azure在云服务提供商中有什么区别
    AWS和Azure在云服务提供商中的区别:1.申请主体差异;2.服务推送频率不同;3.消息提醒机制;4.支付功能异同;5.客服服务对比;6.自定义菜单差异;7.收费细则异同。AWS(亚马逊云服务)和Azure(微软云)是两大主流云服务提供商,它们在云计算领域有着显著的区别。1.申请主体差异AWS主要面向企业和开发......
  • BigDecimalUtil工具类 Java 多种类型(Double, String, Integer)转换成BigDecimal 进行加
    工具说明没有什么太复杂的代码。先是通过方法名称确定返回值的类型(BigDecimal、Double、String)。然后大量的重载方法,用“穷举法”把BigDecimal、Double、String、Integer四种类型进行各种形式的两两组合,进行加减乘除运算。运算时非BigDecimal类型的参数会转化成BigDecim......
  • JavaScript 实现购物车数量增加减少功能
    场景描述在实现购物车功能时,需要限制用户加购的数量必须大于0且不超过加购商品的库存量。代码实现下列代码中,<input></input>中使用min属性定义数量的最小值,max属性定义数量的最大值。在实际开发中可以整合springboot和thymeleaf,使用th:max="${商品对象的库存量}"将ma......
  • 带余除法题解
    题面带余除法题目背景注意:提交至洛谷时,请使用标准输入输出,而非文件输入输出。NOTICE:WhensubmittingyourcodeonLuogusite,pleaseusestandardIOinsteadoffileIO.点我(或在本题底部)下载中文试题PDF。Clickhere(oratthebottomofthispage)todownload......
  • 计算机组成原理之浮点数的加减运算
    计算机组成原理之浮点数的加减运算主要涉及以下几个步骤:1、对阶:由于浮点数的阶码不同,小数点位置不同,不能直接进行尾数加减。首先求两数阶码之差,通过小数阶向大数阶看齐的原则,对阶码小的尾数进行移位(右移),每右移一位,阶码加1,直到两数阶码相等。2、尾数加减:对阶后,尾数的小数点......