大数字加法(C语言实现)
大数字加法的实现(C)
C语言的内置类型int
(32位系统下为4字节,32位),无符号整型最大可表示232-1=2147483647(字符长度为10位),而signed long long
也最大为264-1=18446744073709551999(字符长度为20位),如果要计算更大的数的加法运算,计算机将无法存储这些数字,所以要转换为对字符串的处理。
可以使用小学学到的竖式计算的方式来处理,从个位开始逐位相加,和大于10则进位。
这里首先要考虑到字符串表示的大数在内存的存储方式,数字的位越高对应的数组的索引越小,即个位的数字字符在数组末尾。所以需要先将数字字符串逆序,然后将每一位使用字符对应的真实数值进行计算放入新的数组,最后将结果数组的每一个值还原为字符值并逆序输出。
解决思路
1. 先将相加的两个大数字符串num1[]和num2[]逆序处理
inline void swap(unsigned char * x, unsigned char * y)
{*x += *y;*y = *x - *y;*x = *x - *y;
}char * strReverse(char * str)
{char * start = str;char * end = str + strlen(str) - 1;while(start < end) swap((unsigned char *)start ++, (unsigned char *)end --); //对称交换头和尾return str;
}
这里swap
是交换两个unsigned char
类型变量的值,使用内联可以避免函数调用的栈开销,提高运行效率。
2. 每一位都转换为真实数值:c -= '0'
void transToRealVal(char * str, int len)
{char * start = str;char * end = str + len - 1;while(start <= end) {*start -= '0'; start ++;}return;
}
3. 从低到高逐位相加(注意进位)存入新的数组result[]
char * bignumPlus(char * num1, char * num2, int resultLen)
{strReverse(num1);strReverse(num2);transToRealVal(num1, strlen(num1));transToRealVal(num2, strlen(num2));char * result = malloc_type(char, resultLen);int resultSize = 0;int i = 0;for(i = 0; i < resultLen - 1; i ++){result[i] += (num1[i]+ num2[i]);resultSize = i + 1;if(result[i] >= 10) //向高位进位{result[i + 1] += 1;result[i] %= 10;resultSize ++;}}transToCharVal(result, resultSize);strReverse(result); return result;
}
4. 将result[]每一位都还原为数字对应的字符值:c += '0'
void transToCharVal(char * str, int len)
{char * start = str;char * end = str + len - 1;while(start <= end){*start += '0'; start ++;}return;
}
需要注意的是字符串参数str
的每一位都是真实数值,中间某一个值可能为0,不能用strlen()
取长度,必须传入参数len
来确保str
的真实长度。
5. 将result[]逆序处理
同1.
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define Max(x,y) ((x) > (y) ? (x) : (y))
#define Min(x,y) ((x) < (y) ? (x) : (y))#define malloc_type(type, num) (type *)malloc(num * sizeof(type)) char * strdump(char * str, int size)
{char * string = (char *)malloc(size + 1);if(!string)return NULL;memset(string, '\0', size + 1);memcpy(string, str, Min(strlen(str), size));return string;
}void strfree(char ** str)
{if(*str){free(*str);*str = NULL;}
}inline void swap(unsigned char * x, unsigned char * y)
{*x += *y;*y = *x - *y;*x = *x - *y;
}char * strReverse(char * str, int len)
{char * start = str;char * end = str + Min(len, strlen(str)) - 1;while(start < end) swap((unsigned char *)start ++, (unsigned char *)end --);return str;
}void transToRealVal(char * str, int len)
{char * start = str;char * end = str + len - 1;while(start <= end) {*start -= '0'; //'RVal(*start);start ++;}return;
}void transToCharVal(char * str, int len)
{char * start = str;char * end = str + len - 1;while(start <= end){*start += '0'; //''CVal(*start);start ++;}return;
}char * bignumPlus(char * num1, char * num2, int resultLen)
{strReverse(num1);strReverse(num2);transToRealVal(num1, strlen(num1));transToRealVal(num2, strlen(num2));char * result = malloc_type(char, resultLen);int resultSize = 0;int i = 0;for(i = 0; i < resultLen - 1; i ++){result[i] += (num1[i]+ num2[i]);resultSize = i + 1;if(result[i] >= 10){result[i + 1] += 1;result[i] %= 10;resultSize ++;}}transToCharVal(result, resultSize);strReverse(result); return result;
}void destoryResult(char ** result)
{if(*result){free(*result);*result = NULL;}
}int main(int argc, char ** argv)
{int numLen1 = strlen(argv[1]);int numLen2 = strlen(argv[2]);int resultLen = Max(numLen1, numLen2) + 1; //此处+1考虑到最高位进位,计算结果的长度增加printf("resultLen=[%d]\n", resultLen);char * fmt = strdump("", 64); sprintf(fmt,"[%%%ds]\n", resultLen);//格式化输出,个位对齐char * num1 = strdump(argv[1], resultLen);printf(fmt, num1);char * num2 = strdump(argv[2], resultLen); printf(fmt, num2);//char * result = bignumPlus(num1, num2, resultLen);printf(fmt, result);//destoryResult(&result); //销毁结果strfree(&fmt);strfree(&num1);strfree(&num2);return 0;
}
运行结果
这里使用的linux环境,源码文件为bigNumPlus.c, 用gcc
编译:
gcc -g -Wall -O3 -o bigNumPlus bigNumPlus.c
测试结果
两个数位数相同时
root@ubuntu:/home/ubuntu/Github# ./bigNumPlus 3 5
resultLen=[2]
[ 3]
[ 5]
[ 8]root@ubuntu:/home/ubuntu/Github# ./bigNumPlus 8 5
resultLen=[2]
[ 8]
[ 5]
[13]
root@ubuntu:/home/ubuntu/Github# ./bigNumPlus 1324515231423212344 8231472653421234213
resultLen=[20]
[ 1324515231423212344]
[ 8231472653421234213]
[ 9555987884844446557]root@ubuntu:/home/ubuntu/Github# ./bigNumPlus 29834728347283498678234092374 92340923947023947628346928348
resultLen=[30]
[ 29834728347283498678234092374]
[ 92340923947023947628346928348]
[122175652294307446306581020722]
两个数位数不相同时
root@ubuntu:/home/ubuntu/Github# ./bigNumPlus 29283742834238468273642039456234 9234092394702323423652345
resultLen=[33]
[ 29283742834238468273642039456234]
[ 9234092394702323423652345]
[ 29283752068330862975965463108579]root@ubuntu:/home/ubuntu/Github# ./bigNumPlus 1234567893244523452345234584567523234598293465928364502374659029783452345456230345456 34534634567345672345623462345763456733453345634563456345754694057823465234567453645309237452093487528345023904
resultLen=[111]
[ 1234567893244523452345234584567523234598293465928364502374659029783452345456230345456]
[ 34534634567345672345623462345763456733453345634563456345754694057823465234567453645309237452093487528345023904]
[ 34534634567345672345623463580331349977976797979798040913277928656116931162931956019968267235545832984575369360]
总结
本文章简单地实现了大数字加法运算,有几个细节需要注意到,此外大数字的减法、乘法和除法可以参考加法的实现思路,对于带小数的大数字运算对小数部分可以单独处理,但是要参考浮点数的表示原理,与整数部分不一样。另外程序要尽可能的优化,减少不必要的操作和无意义的变量,对数组的操作要准确,防止越界。
大数字加法(C语言实现)相关推荐
- 大整数加法——C语言
高精度计算--大整数加法 这是我写过的程序,主要也是为记录和学习,以下代码是该程序的思路和答案(注释是我自己写的),如有不对,请指出. 问题描述 求两个不超过200位的非负整数的和. 输入数据 有两行 ...
- NOI OJ 1.6 10:大整数加法 C语言
描述 求两个不超过200位的非负整数的和. 输入 有两行,每行是一个不超过200位的非负整数,可能有多余的前导0. 输出 一行,即相加后的结果.结果里不能有多余的前导0,即如果结果是342,那么就不能 ...
- c语言怎么进行大整数加法,c语言 大整数加法
2013-12-07 回答 以前我也做过一个大整数程序,2000!,不过那里面没有减法.做这个减法真让花时间啊. #include #include #include #define max 4000 ...
- Java快速入门到精通—大数字运算(BigDecimal 类)
在Java中提供了用于大数字运算的类,即 java.math.BigInteger 类和 java.math.BigDecimal 类.这两个类用于高精度计算,其中BigInteger 类是针对整型大 ...
- 大整数加法(详细讲解C++)
小白的自我成长之路 1. 整数运算 C语言的整数类型往往无法支持过大的数字加法计算. 在C++中实现大数据的运算,则需要借助其他方法(数据类型)实现.在实际操作当中使用数组或者vector容器进行储存 ...
- C++实现大整数加法
大整数加法可谓是学习C++语言的一个里程碑.那么,如何在C++简单易懂地实现大整数加法呢? 概念思路 假定这两个十进制的大整数位数不超过255位. 那么,可以定义两个长度为255的字符数组(num1, ...
- 4、大数字运算(BigInteger类和BigDecimal类)
在 Java 中提供了用于大数字运算的类,即 java.math.BigInteger 类和 java.math.BigDecimal 类.这两个类用于高精度计算,其中 BigInteger 类是针对 ...
- 剑指offer第12题打印从1到n位数以及大整数加法乘法
字符和数字加减就是字符的ASCII码和数字直接加减. 方法一: 1)在字符串操作中给一个整形数字加(字符0)就是把它转化为字符,当然给一个字符减去(字符0)就可以把它转化为数字了:如果确实是最后一位字 ...
- java biginteger 运算_Java大数字运算之BigInteger 原创
在 Java中,有许多数字处理的类,比如Integer 类.但是Integer 类有一定的局限性,下面我们就来看看比 Integer 类更厉害的一个,BigInteger类. BigInteger类型 ...
- 如何用C++来计算大数字乘法
C++是比较高效地语言,用来做大鼠乘法效应一定没得说,那么如何用C++来计算大数字乘法,下面给出一个方法. 题解:用字符数组存两个因数,再将数组逆序以便处理,再对每一个数位进行处理,注意字符类型 ...
最新文章
- Python 写了一个网页版的「P图软件」,惊呆了!
- 基于深度学习的目标检测算法:SSD——常见的目标检测算法
- python2基础教程廖雪峰云-Python基础
- leetcode算法题--最长的斐波那契子序列的长度
- 【JVM】jstack和dump线程分析(2)
- struts2获取服务器临时目录
- 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 12—Support Vector Machines 支持向量机...
- java-二分查找树的实现
- 建立学生选课表 mysql 语句_MySQL常用SQL语句(Python实现学生、课程、选课表增删改查)...
- C - Digital Path 计蒜客 - 42397 05-29
- MySQL数据库创建用户root@%
- python batch normalization_Batch Normalization 详解
- java jackson unicode_如何让Jackson JSON生成的数据包含的中文以unicode方式编码
- 【比原链】比原启动后去哪里连接别的节点
- oracle统计每个类别,Oracle统计分析函数集之一
- NGINX(二)内存池
- 嵌套的SQL另外一种写法
- 华为2台3928千兆电口对接trunk启不来
- 基于STM32移植UCGUI图形界面框架(3.9.0源码版本)
- 淘宝大数据产品解析之淘宝数据魔方技术架构(1)
热门文章
- 未援与用户在此计算机,在里番世界里拯救世界
- ERROR: pip‘s dependency resolver does not currently take into account all the packages that are ....
- 20个免费的SEO网站分析工具
- Python Requests爬取百思不得姐视频
- 酵素果冻在快手火了!三个品牌单品一周卖出5000万背后的秘密是什么?
- noip2018翻车记
- 记一次github 翻车事件
- 500 The server encountered an unexpected condition that prevented it from fulfilling the request.
- linux基础-命令
- Microsoft Word 教程:如何在 Word 中插入表格?