IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 基础算法一:C++高精度计算(加,减,乘,除)详解 -> 正文阅读

[C++知识库]基础算法一:C++高精度计算(加,减,乘,除)详解

一、前言:

????????有些计算要求精度高,希望计算的数的位数可达数十位或数百位,但因受到硬件的限制,往往很难达到实际问题所要求的精度。

二、在数据的处理中需要的几个要素:

(1)数据的接收方式/存贮方法:

? ? ? ? 输入的数很长,则可采用字符串方式输入,这样可输入位数很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组。

void init(int a[])          //传入一个数组
{
  string s;
  cin>>s;                   //读入字符串s
  len=s.length();           //用len计算字符串s的位数
  for(i=1;i<=len;i++)
    a[i]=s[len-i]-'0';      //将字符串s转换为数组a,并倒序储存
}

另一种方法是直接用循环加数组方法输入数据。

(2)高精度位数的确定

位数的确定:接受时往往是用字符串的,所以它的位数就等于字符串的长度。

(3)进位,借位处理(先简单理解)

加法进位:

c[i]=a[i]+b[i];
if(c[i]>=10)//进位条件
{
  c[i]%=10;++c[i+1];//取余和进位
}

减法借位:

if(a[i]<b[i])//相减小于0
{
  --a[i+1];a[i]+=10;//先借位,高位减1,低位加10
}
c[i]=a[i]-b[i];

乘法进位:

c[i+j-1]=a[i]*b[j]+x+c[i+j-1];
x=c[i+j-1]/10;
c[i+j-1]%=10;

商与余数处理:

与除数与被除数的位数(精度)情况进行处理。分为(1).高精除以低精 (2).高精除以高精

三、算法

(1)高精度加法,2个正整数求和

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	char ca[100], cb[100];
	int a[100], b[100], c[100], a_len, b_len, c_len, i, x;
	memset(a, 0, sizeof(a));//memset()函数作用是在字符串a中,
	memset(b, 0, sizeof(a));//从第一个存储单位开始,将后面
	memset(c, 0, sizeof(a));//sizeof(a)个空间全部置为'\0',达到初始化字符串的目的。
	gets_s(ca);//低版本可用gets()函数,c++中头文件为#includ<cstdio>
	gets_s(cb);//输入两个相加的数
	a_len = strlen(ca);
	b_len = strlen(cb);
	for (i = 0; i <= a_len - 1; i++)
	{
		a[a_len - i] = ca[i] - '0';//数组ca的字符型整数转化为整形放入数组a中,注意逆序
	}
	for (i = 0; i <= b_len - 1; i++)
	{
		b[b_len - i] = cb[i] - '0';//数组cb的字符型整数转化为整形放入数组b中,注意逆序
	}
	c_len = 1;
	x = 0;
	while (c_len <= a_len || c_len <= b_len)
	{
		c[c_len] = a[c_len] + b[c_len] + x;
		x = c[c_len] / 10;
		c[c_len] %= 10;
		c_len++;
	}
	c[c_len] = x;
	if (c[c_len] == 0)//第一位可能是0或1,如果是0则忽略不输出
		c_len--;
	for (i = c_len; i >= 1; i--)//逆序输出结果
	{
		cout << c[i];
	}
	cout << endl;
	return 0;
}

(2)高精度减法,两个正整数求差。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	//a-b=c
	char ca[100], cb[100], cc[100];
	int a[100], b[100], c[100], a_len, b_len, c_len, i;
	memset(a, 0, sizeof(a));
	memset(b, 0, sizeof(a));
	memset(c, 0, sizeof(a));
	cout << "Please input minuend" << endl; gets_s(ca);//输入被减数
	cout << "Please input subtrahend" << endl; gets_s(cb);//输入减数
	a_len = strlen(ca);
	b_len = strlen(cb);
	if (strlen(ca) < strlen(cb) || (strlen(ca) == strlen(cb) && strcmp(ca, cb) < 0))
		//strcmp()的作用是比较ca和cb,当ca==cb时,返回0;
		//当ca>cb时,返回正整数;ca<cb时,返回负整数;
	{
		strcpy_s(cc, ca);//将ca的值赋给cc,这里cc用作寄存器
		strcpy_s(ca, cb);
		strcpy_s(cb, cc);
		cout << "-";//交换减数与被减数,结果为负
	}
	//下面开始逻辑运算部分
	a_len = strlen(ca);
	b_len = strlen(cb);
	for (i = 0; i <= a_len - 1; i++)
	{
		a[a_len - i] = int(ca[i] - '0');//被减数存入数组a
	}
	for (i = 0; i <= b_len - 1; i++)
	{
		b[b_len - i] = int(cb[i] - '0');//减数存入数组b
	}
	i = 1;
	while (i <= a_len || i <= b_len)
	{
		if (a[i] < b[i])//借位条件,被减数某位小于减数对应位
		{
			a[i] += 10;//低位加10
			a[i + 1]--;//高位减1
		}
		c[i] = a[i] - b[i];//对应位相减
		i++;
	}
	c_len = i;
	while ((c[c_len] == 0) && (c_len > 1))
	{
		c_len--;//最高位可能位0,此时不输出此位
	}
	for (i = c_len; i >= 1; i--)
	{
		cout << c[i];//输出结果
	}
	cout << endl;
	return 0;
}

(3)高精度乘法,两个正整数的积

先作分析:c数组的求和得:ci=c'i+c''i+c'''i+…由此可见,①ci与a[i]*b[j]有关②与上一位的进位有关③c1位上的单个数字与c1本身求得的数有关.

综上有:c[i+j-1]=a[i]*b[j]+x+c[i+j-1];? ?x=c[i+j-1]/10;? ? c[i+j-1]%=10;? 看不懂不要紧,在源码中作具体讲解。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	char a1[100], b1[100];
	int a[100], b[100], c[10000], a_len, b_len, c_len, i, j, x;
	memset(a, 0, sizeof(a));
	memset(b, 0, sizeof(b));
	memset(c, 0, sizeof(c));
	cin >> a1;
	cin >> b1;
	a_len = strlen(a1);
	b_len = strlen(b1);
	for (i = 0; i <= a_len - 1; i++)
	{
		a[a_len - i] = a1[i] - '0';//倒序输入到整型数组
	}
	for (i = 0; i <= b_len - 1; i++)
	{
		b[b_len - i] = b1[i] - '0';
	}
	for (i = 1; i <= a_len; i++)
	{
		x = 0;//存放进位
		for (j = 1; j <= b_len; j++)//对乘数的每一位处理,相当于把乘数各位数拆出,一位数与另一个乘数相乘
		{
			c[i + j - 1] = a[i] * b[j] + x + c[i + j - 1];//当前乘积+进位+原数
			x = c[i + j - 1] / 10;
			c[i + j - 1] %= 10;
		}
		c[i + b_len] = x;//处理进位
	}
	c_len = a_len + b_len;
	while (c[c_len] == 0 && c_len > 1)//删除前导0
		c_len--;
	for (i = c_len; i >= 1; i--)
		cout << c[i];//输出结果
	cout << endl;
	return 0;
}

(4)除法,高精除以低精

做除法时,每一次的商都在0~9,每次求得的余数连接以后的若干位得到新的被除数,继续做除法。因此,在做高精度除法时,要涉及到乘法运算和减法运算,还有位移处理。当然,为了程序简洁,可以避免高精度乘法,用0~9次循环减法取代得到的商的值。这里,我们用按位相除法。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	char a1[100];
	int a[100], c[100], a_len, i, x = 0, c_len, b;
	memset(a, 0, sizeof(a));
	memset(c, 0, sizeof(c));
	gets_s(a1);
	cin >> b;
	a_len = strlen(a1);
	for (i = 0; i <= a_len - 1; i++)
	{
		a[i + 1] = a1[i] - '0';
	}
	for (i = 1; i <= a_len; i++)//按位相除
	{
		c[i] = (x * 10 + a[i]) / b;
		x = (x * 10 + a[i]) % b;
	}
	c_len = 1;
	while (c[c_len] == 0 && c_len < a_len)
	{
		c_len++;//删除前导0
	}
	for (i = c_len; i <= a_len; i++)
	{
		cout << c[i];
	}
	cout << endl;
	return 0;
}

高精除以高精运用减法模拟除法,对被除数的每一位都减去除数,一直减到当前位置的数字(包含前面的余数)小于除数(由于每一位的数字小于10,所以对于每一位最多进行10次运算)较为复杂,此篇文章就不多做赘述。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:28:13  更:2021-07-25 11:29:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 4:50:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码