高精度减法(C语言实现)

这篇具有很好参考价值的文章主要介绍了高精度减法(C语言实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

高精度减法(C语言实现)

介绍

众所周知,整数在C和C++中以intlonglong long三种不同大小的数据存储,数据大小最大可达2^64,但是在实际使用中,我们仍不可避免的会遇到爆long long的超大数运算,这个时候,就需要我们使用高精度算法,来实现巨大数的运算。

高精度的本质是将数字以字符串的形式读入,然后将每一位分别存放入int数组中,通过模拟每一位的运算过程,来实现最终的运算效果。

书接上回,我们今天继续讲解高精度减法的C语言实现:


代码实现

#include<stdio.h>
const int N = 100001;

int cmp(int a[], int b[], int len1, int len2)
{//大小比较函数
	if (len1 > len2)//先对比长度
		return 0;
	else if (len1 < len2)//长度不一样直接返回结果
		return 1;
	else//长度一致则依次比较每一位大小
	{
		for (int i = len1 - 1; i >= 0; i--)
		{
			if (a[i] > b[i])
				return 0;
			if (a[i] < b[i])
				return 1;
		}
	}
	return 0;//如果完全一致则返回0,避免减法函数中调用导致无限递归
}

int minus(int a[], int b[], int c[], int len1, int len2)
{//高精度减法函数
	if (cmp(a, b, len1, len2))//减法函数只计算大减小,小减大则反过来,然后输出时加负号
		return minus(b, a, c, len2, len1);
	int t = 0;//t标识是否借位
	for (int i = 0; i < len1; i++)
	{
		c[i] = (a[i] - b[i] + t + 10) % 10;//c[i]表示这一位运算结果
		if (a[i] - b[i] + t < 0) t = -1;//计算是否借位
		else t = 0;
	}
	int len3 = len1;
	while (c[len3 - 1] == 0)//去除前导0,返回结果的位数
	{
		if (len3 == 1) return len3;
		len3--;
	}
	return len3;
}

int main()
{
	char str1[N], str2[N];//----------------------------
	int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };
	char x;
	int len1 = 0, len2 = 0;
	do
	{
		scanf("%c", &x);
		str1[len1++] = x;

	} while (x != '\n');
	do//                                数据读入部分不作赘述
	{
		scanf("%c", &x);
		str2[len2++] = x;

	} while (x != '\n');
	len1--; len2--;
	for (int i = len1 - 1; i >= 0; i--)
		a[i] = str1[len1 - i - 1] - '0';
	for (int i = len2 - 1; i >= 0; i--)
		b[i] = str2[len2 - i - 1] - '0';//---------------
	int len3 = minus(a, b, c, len1, len2);//执行高精度减法函数
	if (cmp(a, b, len1, len2))//大小比较函数
		printf("-");//结果为负数则打个负号先
	for (int i = len3 - 1; i >= 0; i--)
		printf("%d", c[i]);
	return 0;
}

思路解析

鉴于在高精度加法一篇中我们已经讲解过了数据的读入,所以我们这一篇不再赘述,没看过上一篇的可以点击下方链接:

高精度加法(C语言实现) - 凉茶coltea


高精度减法思路和高精度加法基本一致,区别就是加法考虑进位,减法考虑退位,以及减法的结果的位数变动是极大的。

我们对每一位分别计算,得出结果,存入新数组c,同时用临时变量t来标识是否借位。

但小数减大数的结果是负数,在实际操作中十分不便,所以我们另外声明一个cmp函数来比较二者大小,如果被减数比较小,那我们就可以用减数减去被减数,输出结果前先输出一个负号,达到同样的效果。


数据的读入上,高精度加减乘除基本一模一样,所以我们直接跳到第一个关键部分,大小比较函数:

int cmp(int a[], int b[], int len1, int len2)
{//大小比较函数
	if (len1 > len2)//先对比长度
		return 0;
	else if (len1 < len2)//长度不一样直接返回结果
		return 1;
	else//长度一致则依次比较每一位大小
	{
		for (int i = len1 - 1; i >= 0; i--)
		{
			if (a[i] > b[i])
				return 0;
			if (a[i] < b[i])
				return 1;
		}
	}
	return 0;//如果完全一致则返回0,避免减法函数中调用导致无限递归
}

在数据的读入中,我们已经知道了两数的位数,那就可以通过比较位数来判断二者大小谁长谁大

倘若二者长度一致,那就依次比较每一位的大小,也就是比较二者的字典序。

倘若二者完全一致,那我们返回0,原因后面说。


有了大小比较函数,我们就可以保证计算时是大数减去小数了,这样,我们就规避了负数的困扰,可以更轻松地实现高精度减法的函数:

int minus(int a[], int b[], int c[], int len1, int len2)
{//高精度减法函数
	if (cmp(a, b, len1, len2))//减法函数只计算大减小,小减大则反过来,然后输出时加负号
		return minus(b, a, c, len2, len1);
	int t = 0;//t标识是否借位
	for (int i = 0; i < len1; i++)
	{
		c[i] = (a[i] - b[i] + t + 10) % 10;//c[i]表示这一位运算结果
		if (a[i] - b[i] + t < 0) t = -1;//计算是否借位
		else t = 0;
	}
	int len3 = len1;
	while (c[len3 - 1] == 0)//去除前导0,返回结果的位数
	{
		if (len3 == 1) return len3;
		len3--;
	}
	return len3;
}

如你所见,第一步就是对二者大小的判断,如果被减数比减数小,我们直接改变入参的顺序来改变二者位置。

倘若二者完全一致时cmp返回1,那么再调换位置后,minus函数将继续调用cmp函数来判断二者大小,每次都会返回1,导致无限递归,这就是我们规定完全一致时返回0的原因。

其中我们用c[i] = (a[i] - b[i] + t + 10) % 10;来计算结果的第i位,之所以要+10,是模拟结果为负时向前一位借10的过程,而如果(a[i] - b[i] + t)不为负数,那因为%10的存在,也不会产生影响。

下一行if (a[i] - b[i] + t < 0)也很好理解,若是(a[i] - b[i] + t)为负数,那就需要向前一位借位,那我们就标记t=-1,来影响下一位的结果计算即可。

最后我们需要去除前导0,首先因为运算数都是正整数,所以结果最大位数也就和被减数一样,所以我们从被减数的最高位数开始判断结果c,如果为0,那就把返回的长度len3减去1,而值得注意的是,若是结果只有1位了那就不能减了,因为这意味着结果为0


那此时我们就已经完成了高精度减法的运算,将结果存入了数组c,但别忘了结果正负的判断:

	if (cmp(a, b, len1, len2))//大小比较函数
		printf("-");//结果为负数则打个负号先

如果被减数比减数小,我们需要提前把负号补上。

那就此,大功告成。


结尾

那么以上便是对高精度减法算法的介绍,本文由凉茶coltea撰写,思路来自AcWing,大佬yxc的课程。文章来源地址https://www.toymoban.com/news/detail-742562.html

到了这里,关于高精度减法(C语言实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高精度减法

    要实现两个高精度数的减法,和高精度加法一样都是模拟竖式计算的过程,主要就是解决以下两个问题。 谁大谁小? 由于这两个数字都很大,但是不知道谁更大,所以要先判断哪个数更大,思路如下: 判断这两个数谁的位数更大,位数更大的自然更大。 如果位数不相同,从

    2024年02月08日
    浏览(31)
  • C++基础算法①——高精度加减法计算

    当我们利用计算机进行数值计算,有时候会遇到这样的问题: n!的精确结果是多少? 当n小于30的时候,我们当然可以通过电脑自带的计算器计算出来。但是当我们遇到 100! 的时候就没有办法直接计算出精确的结果。再比如,求两个20000位的数的和。 那怎么解决精度缺失的问

    2024年02月16日
    浏览(26)
  • 算法之高精度(含实例与详解)C语言

           高精度本质上是一种计算,由于int型和long long型的存储的数据大小有限。在有符号定义的情况下,int型为2的31次方减1;在无符号定义的情况下,lint型为2的32次方。因此过于巨大的数无法展示,这就用到了高精度来计算,其原理为将很大的数一位一位存在数组中,最后

    2024年02月06日
    浏览(25)
  • 免费开源的高精度OCR文本提取,支持 100 多种语言、自动文本定位和脚本检测,几行代码即可实现离线使用(附源码)

    免费开源的高精度OCR文本提取,支持 100 多种语言、自动文本定位和脚本检测,几行代码即可实现离线使用(附源码)。 要从图像、照片中提取文本吗?是否刚刚拍了讲义的照片并想将其转换为文本?那么您将需要一个可以通过 OCR(光学字符识别)识别文本的应用程序。 图

    2024年02月01日
    浏览(91)
  • C语言 加减乘除模 的 高精度计算 (超详细)

    目录 高精度加法 高精度乘法 高精度减法          高精度除法 高精度模法   高精度计算 是模拟算法的一种,通过字符串和整型数组的使用,将加减乘除的竖式运算 模拟 出来,达到计算的目的。其步骤大致分为:一,将字符串数据存到整型数组中,二,模拟算法,不同的

    2023年04月24日
    浏览(27)
  • 高精度除法【c++实现】超详细讲解

    高精度算法分为两种,高精除以低精和高精除以高精。不要看都是除法,就认为原理类似,其实是有很大差距的。让我们一起来学习吧! 有句话说在前面,如果除数等于0,就不要算了,不成立。( 如果你忘了这个知识,小学数学老师饶不了你 ) 高精度除低精度,原理是模

    2024年02月13日
    浏览(18)
  • STM32 SYSTick高精度延时功能代码实现

    本篇文章将给大家讲解一下SYSTICK滴答定时器,以及讲解使用滴答定时器来实现高精度延时功能的代码。 SysTick定时器是嵌入式系统中常见的一个系统定时器,在ARM Cortex-M微控制器中广泛使用。下面是关于SysTick定时器的一些介绍: 用途: SysTick定时器通常被用作操作系统的时钟

    2024年02月22日
    浏览(30)
  • Flutter实现PS钢笔工具,实现高精度抠图的效果。

    演示:  代码: stack代码: 主要思路: 更具手指点击屏幕的位置,记录点击的位置,并生成绘制点和两个控制点,手指拖动控制点时,动态刷新控制点位置,然后利用flutter绘制机制,在canvas上根据点的位置和控制点的位置绘制三阶贝塞尔曲线,实现钢笔工具效果。具体实现

    2024年02月07日
    浏览(25)
  • AI模型大杀器----Amazon SageMaker 实现高精度猫狗分类

    前言: Hello大家好,我是Dream。 最近受邀参与了 亚马逊云科技【云上探索实验室】 活动,基于他们的sagemaker实现了机器学习中一个非常经典的案例: 猫狗分类 。最让我惊喜的是的模型训速度比想象中 效果要好得多,而且速度十分迅速,而且总体感觉下来整个过程十分便利

    2023年04月09日
    浏览(23)
  • C语言/C++随机数生成,程序运行时间计时器(含高精度计时器),包括Windows环境与Linux环境

      🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 -  数据结构与算法_勾栏听曲_0 🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️ 📌个人

    2023年04月26日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包