C/C++高精度算法实现思路与代码

 更新时间:2023年11月28日 15:08:37   作者:仍有未知等待探索  
高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家,下面这篇文章主要给大家介绍了关于C/C++高精度算法实现思路与代码的相关资料,需要的朋友可以参考下

前言

由于c++不能进行位数过高的数据运算,所以要通过模拟数组来进行运算,首先是加法。通过char或string型数据输入字符来模拟数字的输入,数组下表对应的元素应当是处于同一位置的数字,下标相同的两个元素相加表示的既是结果。

一、高精度加法

1、思路

其实高精度加法和普通的加法思路没有什么区别。就是个位数先相加,然后判断进位,在把进位进行相加。最后得到结果。

从个位开始进行相加,进位操作。(通过数组进行存储) 

2、代码

#include<iostream>
#include<string>
using namespace std;

const int N = 510;//数字最大可以存储509位的数字
int a[N];//要相加的数字
int b[N];//要相加的数字
int c[N];//得到的结果
int main()
{
    string str1;//要想加的数字
    string str2;//要相加的数字
    cin >> str1;
    cin >> str2;
    //将str1和str2进行逆置存放
    for (int i = 0; i < str1.size(); i++)
        a[str1.size() - 1 - i] = str1[i] - '0';
    for (int i = 0; i < str2.size(); i++)
        b[str2.size() - 1 - i] = str2[i] - '0';
    //得到最大的位数
    int ans = max(str1.size(), str2.size());
    for (int i = 0; i < ans; i++) {
        c[i] += a[i] + b[i];//相加
        c[i + 1] = c[i] / 10;//进位
        c[i] %= 10;//如果1位数大于10,对其进行取余
    }
    ans += 1;//避免最大位数相加完之后有进位:比如说500+500,5+5=10,要进位
    //去除前导0
    if (c[ans - 1] == 0 && ans > 1)
        ans -= 1;
    //输出
    for (int i = 0; i < ans; i++)
        cout << c[ans - 1 - i];
    return 0;
}

二、高精度乘法 

1、思路

  • 按照常规的高精度乘法的思路,分别先用两个数组逆序存储两数,方便计算。
  • 结果的长度必然不会超过两数的长度之和
  • 进行乘法运算时,我们可以先不用考虑进位,按照常规思路直接算。
  • 计算完成后,处理数组中结果大于或等于10的位置,即向前进位。
  • 最后,处理前导零,将结果逆序输出。

高精度乘法和竖式运算的乘法思路是一样的。如图所示:

根据上面的规律可以知道下图的公式。 

2、代码 

#include<iostream>
using namespace std;
const int N = 2000;
int m[N];//要算的数
int n[N];//要算的数
int ans[2 * N];//所得的答案
int main() {
	string a, b;//字符串输入
	cin >> a >> b;
	int la = a.size();//a的字符串长,也就是乘数的位数
	int lb = b.size();//b的字符串长,也就是乘数的位数
	int i = 0, j = 0;
	//逆序存入数组中
	for (i = 0; i < la; i++) {
		m[i] = a[la - i - 1] - '0';
	}
	//逆序存入数组中
	for (j = 0; j < lb; j++) {
		n[j] = b[lb - j - 1] - '0';
	}
	//根据公式进行计算
	for (i = 0; i < la; i++) {
		for (j = 0; j < lb; j++) {
			ans[i + j] += m[i] * n[j];
		}
	}
	//上述仅进行了计算各个位的数,没有考虑进位
	//下面循环考虑进位
	//ns为答案的位数,由例子可知,答案的位数的最小值为la+lb-1
	int ns = la + lb - 1;
	for (i = 0; i < ns; i++) {
		//各位大于9时,才考虑进位的问题
		if (ans[i] > 9) {
			ans[i + 1] += ans[i] / 10;
			ans[i] %= 10;
		}
		//如果i+1进位大于ns,ns要进行更新
		if (i + 1 > ns) {
			ns++;
		}
	}
	//逆序打印
	//考虑先导0的问题
	if (ans[i] == 0 && ns > 1)
		ns--;
	for (i = ns; i >= 0; i--) {
		cout << ans[i];
	}
	return 0;
}

附:c++高精度浮点数计算

C++自带的float和double类型精度有限,无法进行高精度计算。如果需要进行高精度浮点数计算,可以使用第三方库,如GMP(GNU Multiple Precision Arithmetic Library)和MPFR(Multiple Precision Floating-Point Reliable Library)等。

以下是使用GMP库进行高精度浮点数计算的示例代码:

#include <iostream>
#include <gmpxx.h>

int main()
{
    mpf_set_default_prec(64); // 设置默认精度为64位
    mpf_class a("123.456"); // 定义高精度浮点数a
    mpf_class b("789.012"); // 定义高精度浮点数b
    mpf_class c; // 定义高精度浮点数c
    c = a + b; // 高精度浮点数加法
    std::cout << c << std::endl; // 输出结果
    return 0;
}

上述代码中,mpf_class是GMP库中表示高精度浮点数的类,mpf_set_default_prec函数用于设置默认精度,mpf_class的构造函数可以接受字符串或整数作为参数,进行高精度浮点数的初始化,高精度浮点数的加法和输出结果的方式与普通浮点数相同。

总结

到此这篇关于C/C++高精度算法实现思路与代码的文章就介绍到这了,更多相关C/C++高精度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Matlab利用垂距法实现提取离散坐标数据特征点

    Matlab利用垂距法实现提取离散坐标数据特征点

    垂距法是指根据中间顶点到其前、后两相邻顶点连线的距离的大小,来确定是否保留该顶点的一种线要素顶点压缩算法。本文将利用这一算法实现提取离散坐标数据特征点,需要的可以参考下
    2022-04-04
  • VS2022连接sqlserver数据库教程

    VS2022连接sqlserver数据库教程

    本文主要介绍了VS2022连接sqlserver数据库教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 一篇文章带你了解C++ static的作用,全局变量和局部变量的区别

    一篇文章带你了解C++ static的作用,全局变量和局部变量的区别

    这篇文章介绍了C++ static的作用,全局变量和局部变量的区别,需要的朋友可以过来参考下,希望能够给你带来帮助
    2021-09-09
  • C++求1到n中1出现的次数以及数的二进制表示中1的个数

    C++求1到n中1出现的次数以及数的二进制表示中1的个数

    这篇文章主要介绍了C++求1到n中1出现的次数以及数的二进制表示中1的个数,两道基础的算法题目,文中也给出了解题思路,需要的朋友可以参考下
    2016-02-02
  • C++关于Makefile的详解含通用模板

    C++关于Makefile的详解含通用模板

    今天小编就为大家分享一篇关于C++关于Makefile的详解含通用模板,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • C语言教程之数组详解

    C语言教程之数组详解

    这篇文章主要为大家介绍了C语言教程之数组,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • QT设置widget背景图片不影响widget内其他控件背景的方法

    QT设置widget背景图片不影响widget内其他控件背景的方法

    这篇文章主要给大家介绍了关于QT设置widget背景图片不影响widget内其他控件背景的方法,软件的界面为了更直观或美观,常常需要通过图片来表达,需要的朋友可以参考下
    2023-06-06
  • C++设计模式之CRTP的使用

    C++设计模式之CRTP的使用

    CRTP全称是curious recurring template pattern,即奇异递归模版模式,是一种c++的设计模式,精巧地结合了继承和模板编程的技术,下面就跟随小编一起来学习一下CRTP的使用吧
    2023-10-10
  • vs2019安装及简单处理技巧(超详细)

    vs2019安装及简单处理技巧(超详细)

    这篇文章主要介绍了vs2019安装及简单处理方法,本文是一篇非常详细的教程,通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • visual studio2019的安装以及使用图文步骤详解

    visual studio2019的安装以及使用图文步骤详解

    这篇文章主要介绍了visual studio2019的安装以及使用图文步骤详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03

最新评论