大数运算法则

大数运算法则

自从准备考研(浙江大学西方经济学专业,若有浙大学生(毕业生也可)或者备考浙大的研友请留下联系方式,或者加QQ群:57776200)以来,到现在已有半年了。在这半年中,与考研无关的爱好兴趣全都沉没了----因此以前的网名为“潜龙勿用”也有这层含义。我所挚爱的perl、哲学、心理学、古典文学等等,半年多没碰了!疼!

十天前,复习线性代数突然想到乘法也可以这么做:
123 * 456= ?
   1  2   3
4  4  8  12
5  5 10  15
6  6 12  18

斜线相加得5个和:4,13,28,27,18.然后将他们这样计算:
4
13
28
  27
+  18
---------
56088
so 123 * 456 = 56088
当然,这对于人来说有点麻烦,但是计算机可是很在行的呀。按照这一简单法则和其他思想,我编写了加、减、乘、除大数计算程序。除法程序可以精确小数点后到数千位以上。现只将乘法算法附上:
#!/usr/bin/perl -w
use strict;
print "big one>>\n";
chomp(my $one=<>;
print "big two>>\n";
chomp(my $two=<>;
my @ary1=split(//,$one);
my @ary2=split(//,$two);
my($i,$j)=($#ary1,$#ary2);
my @facs;
for my $ind (0..$i+$j){
my $head=$ind<=$i?0ind-$i;
my $start=$ind<$i?$indi;
for(;$start>=0 && $head<=$j;$start--,$head++){
$facs[$ind]+=$ary1[$start] * $ary2[$head];
  }
}
my($relic,$prod)=(0,'');
while(@facs){
my $num=pop @facs;
$prod=(($num + $relic) % 10) . $prod;
$relic= int(($num + $relic)/10);
}
print "prod ==\n",$relic>0?$relic.$prodprod;


都是一些简单的程序,其他的大数除、加、减就不必附上了。
但完全靠自己想到这样做乘法,还是不容易的---但我就做到了!
该程序只能计算正整数。关于计算带多位小数的大数相乘的算法,几乎和该算法一样,还是要以字窜形式存储并参与运算(perl是这方面的超级天才!),只是将结果加个点而已。就这么简单。而除法是乘法的逆运算,原理没什么不同,想让结果精确到小数点后多少位都行。其他大数小数算法,本人均已写好,有时间可能会传上来。

格式出了点问题
“” 表示:和$
我是小学三年级时,从下面这本书上知道古阿拉伯人就已经懂得这么做了:
http://product.dangdang.com/product.aspx?product_id=8781713
看懂了 对角线是什么了



QUOTE:
so 1234 * 456 = 56088

??????

1234*456 = 562704
FLW你太厉害了!!!!!!!!!!
我太落伍了!
哎,看来闭门造车、奋己之私智注定要落伍的!


QUOTE:
原帖由 hitsubunnu 于 2008-7-22 13:51 发表


??????

1234*456 = 562704

sorry 应是123 * 456 = 56088


QUOTE:
原帖由 flw 于 2008-7-22 13:40 发表
我是小学三年级时,从下面这本书上知道古阿拉伯人就已经懂得这么做了:
http://product.dangdang.com/product.aspx?product_id=8781713

找了会儿《算得快》,原本想怀怀旧的,可居然没找到有电子版。
不过找到了这个,用的就是楼主的方法:

http://math.sjtu.edu.cn/gdds/arithmetic.htm

QUOTE:
在乘法运算方法上,一大成果是开始了笔算(欧洲人原来也使用各种“算盘”作计算)。首先发展的是一种源于阿拉伯人的。格子”算法,在欧洲,它出现在最早出版的印刷本算术书中(1478年)。方法如下图,表示943x314,乘数和被乘数分别写在格子的上方和右方。每两个数的积写在格子里,斜行相加便得答数293276。后来才出现现代通用的笔算乘法格式。

不过那时还没有线性代数,这种方法只是“笔算”的萌芽罢了。
古阿拉伯商人们用树枝在沙漠上画格子,来计算自己贸易的收入。