高精度运算总结

目前在oj上遇到的高精度运算有以下几类

  • 高精度整数+高精度整数(poj 2413)
  • 高精度整数×普通整数(poj 1001、poj 1306)
  • 高精度整数×高精度整数(poj 1405)
  • 普通整数÷普通整数(商为高精度浮点数)(poj 1131)
  • 高精度数÷普通整数(poj 1220、poj 1306)
高精度整数+高精度整数:
简单。用两个整数数组分别保存加数(a[0]保存最低位),然后逐个元素相加并计算进位。可以一个元素保存一位,也可一个元素保存多位,后者效率更高,但前者能避免输出时的错误。譬如:若一个元素保存三位,则123003004被保存为a[0] = 4, a[1] = 3, a[2] = 123,此时直接输出的结果为12334,明显错误。因此,一个元素保存多位时,记得在输出时补足前导0,具体方法为printf("%0nd", a[i]),表示用0补足n位。示例代码如下:
cf = 0;  //cf表示进位
for(int i = 0; i < SIZE; i++){  //一个元素保存一位
    c[i] = a[i]+b[i]+cf;
    cf = c[i] > 9 ? 1 : 0;
    c[i] %= 10;
}

高精度整数×普通整数:
简单。高精度整数仍然用整数数组保存,然后用普通整数与该数组的元素逐个相乘并计算进位。下面的代码仍采用一个元素保存一位的策略:
cf = 0;
for(int i = 0; i < SIZE; i++){
     b[i] = a[i]*x+cf;  //x为乘数
     cf = b[i]/10;
     b[i] %= 10;
}

高精度整数×高精度整数:
见另一文章《大数乘法》

普通整数÷普通整数,商为高精度浮点数:
简单。我们采用模拟除法,商的整数部分直接除得,小数部分进行如下循环:将上一次除法所得余数×10,进行除法,获得商的“一位”。示例代码如下:
printf("%d.", a/b);  //a为被除数,b为除数
r = a%b;
while(r != 0){  //这里假设能除尽。若除不尽则应设定循环次数,即小数点后的位数,否则会造成无限循环
    a = r*10;
    printf("%d", a/b);
    r = a%b;
}


高精度数÷普通整数:

较难,类似于上面的普通整数÷普通整数求高精度浮点数商。基本思路是:对被除数从高位开始逐位按权累加并与被除数作除法,所得结果为商的某一位,余数计入累加和。若累加和小于被除数,则跳过本次除法使商的该位为0。商可直接原地保存至被除数数组。示例代码如下:

last = 0;  
int i;
for(i = size-1; i >= 0; i--){  //a[]为被除数数组,b为除数
	cur = last*10+a[i];  //累加和操作
	if(cur < b){
		a[i] = 0;
		last = cur;
	}
	else{
		a[i] = cur/b;
		last = cur%b;  //余数计入下次累加和
	}
}
for(i = size-1; i >= 0; i--)  //去除商数组的冗余后缀0
	if(a[i] != 0) break;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值