c语言用数组存储高精度数,C语言 高精度算法

综合以上所述,对上面两种数据结构取长补短:用字符串读入数据,用数组存储数据。

2.

运算过程:

(1)

运算顺序

:两个数靠右对齐;从低位向高位运算;先计算低位再计算高位;

(2)运算规则:同一位的两个数相加再加上从低位来的进位,成为该位的和;这个和去掉向高位的进位就成为该位的值;如上例:3+8+1=12,向前一位进1,本位的值是2;可借助MOD、DIV运算完成这一步;

(3)最后一位的进位:如果完成两个数的相加后,进位位值不为0,则应添加一位;

(4)如果两个加数位数不一样多,则按位数多的一个进行计算。

3. 结果的输出(这也是优化的一个重点):

按运算结果的实际位数输出4.

优化:

(1)浪费空间:一个整型变量(-32768~32767)只存放一位(0~9);

(2)浪费时间:一次加减只处理一位;

之前写的高精度加法计算Pascal代码如下:(可以根据上面高精度计算能解决的四个问题来理解)

program test;

type

my_arr=array [0..100] of longint;

var

str1,str2:string;

d1,d2,d3:my_arr;

procedure replace(str:string;var arr:my_arr);

var

i,j:longint;

begin

arr[0]:=length(str);

for i:=1 to arr[0] do

begin

arr[i]:=ord(str[arr[0]-i+1])-ord('0');

end;

end;

function max(i,j:longint):longint;

begin

if i>j then exit(i);

exit(j);

end;

procedure add_arr(arr1,arr2:my_arr;var arr3:my_arr);

var

i,j,k,t:longint;

begin

fillchar(arr3,sizeof(arr3),0);

k:=max(arr1[0],arr2[0]);

for i:=1 to k do

begin

t:=(arr1[i]+arr2[i]+arr3[i]);

arr3[i]:=t mod 10;

arr3[i+1]:=t div 10;

end;

if arr3[k+1]<>0 then

arr3[0]:=k+1

else

arr3[0]:=k;

end;

procedure print_arr(arr:my_arr);

var

i:longint;

begin

if arr[0]=0 then

begin

writeln(0);

exit;

end;

for i:=arr[0] downto 1 do

write(arr[i]);

writeln;

end;

begin

readln(str1);

replace(str1,d1);

readln(str2);

replace(str2,d2);

add_arr(d1,d2,d3);

print_arr(d3);

end.

笔者大一的时候学了一种新的编程语言叫做C语言,相信很多同学都已经接触过C语言了,今天在xiaoz吧看到某无良吧主发的题目,我就说这题目不是一般a+b,这家伙还一直狡辩,现在我来跟大家分享一下有关高精度计算的C语言算法。

不多说,当然先上无良吧主今日分享的题目,见下图:83de77ab39e69cd6986e11f924442c1a.png

首先我来分析一下这道题目,这道题目的case2:112233445566778899+998877665544332211=1111111111111111110,看到这个数字很多同学就开始想了,我能不能用long int或者double型呢?

Double 变量以带符号的 IEEE 64 位(8 个字节)双精度浮点数形式存储,负值取值范围为 -1.79769313486231570E+308 到 -4.94065645841246544E-324,正值取值范围为 4.94065645841246544E-324 到 1.79769313486231570E+308。

long int 的取值范围为

-2147483648至2147483647,很显然,是不能用long int的,如果使用long int,则数据溢出。

如果使用double型,则运算速率会非常慢。大家可以试试。最好让无良的吧主去试试。烦死他!

OK,现在,我来说说这道题目的正确算法。这道题目明显就是必须要用高精度计算。

因为是任意长的二整数求和,而系统中整型数的精度有限,因此需用字符串形式存储整数,并按位逐

位进行运算,运算过程中需考虑进位和借位的问题。再者,整数可以是负数,若二整数符号相同则为加法运

算,相异则实为减法运算,若是减法运算还需比较二数的绝对值大小,以确定最终结果的符号及减数与被

减数的安排顺序。

无良吧主出的出的拿到题目正确算法如下:(大家可以任意输入数字检验)

#include#include#define MAX 1000 /*宏定义,下面遇到MAX的时候都变成1000 */

int main(void)

{

unsigned char arr1[MAX]={0},arr2[MAX]={0};

int len,i,len1,len2,t,j = 0;

char str[MAX]; /*读入数据,并进行预处理(计算出数字位数,并反方向存放)*/

scanf("%s",str);

len1 = strlen(str);

for(i=0; ilen2)?len1:len2;

for(i=0; i

算法的思路:

模拟我们在小学所学的笔算

(对于不足位用0补齐,如9818+13,我们认为是9818+0013),

假设我们要计算的两数分别是 A1 A2 A3 A4 、 B1 B2 B3 B4。

那么我们笔算时,会列出这样的式子

A1  A2  A3  A4

+B1  B2  B3  B4

---------------------

C0  C1 C2 C3 C4

那么我们在计算机中也同样可以完成这个过程。为了方便进位,我们在计算前,将两个数反向储存至数组中,即我们是对  B4 B3 B2 B1 、A4 A3 A2 A1 进行计算。初始化时 j = 0,其中有恒等式   Cn  = (An + Bn + j)mod  10  (j为进位结果),根据这个等式我们只需要循环执行以下三步,就能得到大致结果:

1.

temp = An + Bn +j

2.

Cn = temp mod 10

3. j

= temp div 10

循环完成后,我们还需要进行最后一步,因为两个最高位相加仍可能产生进位,所以,我们在这里还要额外做一次对 j 的判断,如果 j 值为 1 的话, Cn+1 应该要进位,即 Cn+1 = 1。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值