基于Ruby的任意精度算法

基于Ruby的任意精度算法,ruby,math,bignum,arbitrary-precision,Ruby,Math,Bignum,Arbitrary Precision,鲁比是怎么做到的?约格或其他人知道幕后发生了什么吗 不幸的是,我不太了解C,所以对我帮助不大。我只是有点好奇,有人能(用简单的英语)解释它所使用的任何奇迹算法背后的理论 irb(main):001:0> 999**999 368063488259223267894700840060521865838338232037353204655962143702569930047223153010387361450517521869134525758963911303931894447969771

鲁比是怎么做到的?约格或其他人知道幕后发生了什么吗


不幸的是,我不太了解C,所以对我帮助不大。我只是有点好奇,有人能(用简单的英语)解释它所使用的任何奇迹算法背后的理论

irb(main):001:0> 999**999
3680634882592232678947008400605218658383382320373532046559621437025699300472231530103873614505175218691345257589639113039318944479697716458323821923660765366131132001776175977932178870367784655811830827898201412402297156781317249494949281043271030787167678146195241804073439869529341169965172727272727201735173517171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717151959779536852290090377452502236990839453416790640456116471139751546750048602189291028640970574762600185950226138244530187489211615864021135312077912018844630780307462205252807737757672094320692373101032517459518497524015120165166724189816766397247824175394802028228160027100623998873667435799073054618906855460488351426611310634023489044291860510352301912426608488807462312126590206830413782664554260411266378866626653755763627796569082931785645600816236891168141774993267488171702172191072731069216881668294625679492696148976999868715671440874206427212056717373099639711168901197440416590226524192782842896415414611688187391232048327738965820265934093108172054875188246591760877131657895633586576611857277011782497943522945011248430439201297015119468730712364007639373910811953430309476832453230123996750235710787086641070310288725389595138936784715274150426495416196669832679980253436807864187160054589045664027158817958549374490512399055448819148487049363674611664609890030088549591992466360050042566270348330911795487647045949301286614658650071299695652245266080672989921799342509291635330827874264789587306974472327718704306352445925996155619153783913237212716010410294999877569745287353422903443387562746452522860420416689019732913798073773281533570910205207767157128174184873357050830752777900041943256738499067821488421053870869022738698816059810579221002560882999884763252161747566893835178558961142349304466506402373556318707175710866983035313122068321102457824112014969387225476259342872866363550383840720010832906695360553556647545295849966279980830561242960013654529514995113584909050813015198928283202189194615501403435553060147713139766323195743324848047347575473228198492343231496580885057330510949058490527738662697480293583612233134502078182014347192522391449087738579081585795613547198599661273567662441490401862839817822686573112998663038868314974259766039340894024308383451039874674061160538242392803580758232755749310843694194787991556647907091849600704712003371103926967137408125713631396699343733288014254084819379380555174777020843568689927348949484201042595271932630685747613835385434424807024615161848223715989797178155169951121052285149157137697718850449708843330475301440373094611119631361702936342263219382793996895988331701890693689862459020775599439506870005130750427949747071390095256759203426671803377068109744629909769176319526837824364926844730545524646494321826241925107158040561607706364484910978348669388142016838792902926158979535543248361611517588605967453958061959024834251561979634775210958214356199673012837673457432890896827103502442222900178912804197827678037857956083472969249991170004998999


它使用Bignum类

irb(main):001:0> (999**999).class
=> Bignum

当然是可用的

您可以阅读


在一个非常高的层次上,在不涉及任何实现细节的情况下,
bignum
s是“手工”计算的,就像你在小学时做的那样。现在,当然有许多优化可以应用,但这就是它的要点。

我不知道实现细节,所以我将介绍基本的大数字实现是如何工作的

基本上,它不依赖CPU“整数”,而是使用多个CPU整数创建自己的整数。为了存储任意精度,假设有2位。所以现在的整数是11。您想添加一个。在正常的CPU整数中,这将滚动到00

但是,对于大数字,它将分配另一位并模拟加法,而不是滚动并保持“固定”整数宽度,从而使数字成为正确的100


试着查一查二进制数学是如何在纸上完成的。它非常简单,转换成算法也很简单

很简单:从一年级开始,它就和你做的一样。除了不以10为基数计算外,它以40亿为基数计算(和变化)

想想看:使用我们的数字系统,我们只能表示从
0
9
的数字。那么,我们如何在不溢出的情况下计算
6+7
?简单:我们真的溢出了!我们不能将
6+7
的结果表示为
0
9
之间的数字,但我们可以溢出到下一个位置,并将其表示为
0
9
之间的两个数字:3×100+1×101。如果要添加两个数字,请从右开始按数字添加,然后从左开始溢出(“进位”)。如果你想把两个数相乘,你必须把一个数的每一位分别与另一个数相乘,然后把中间的结果相加

BigNum算术(这是一种通常称为数字大于本机机器数字的算术)的工作方式基本相同。除了基数不是10,也不是2,它是一个本机整数的大小。所以,在32位机器上,它应该是基232或4 294 967 296

具体地说,在Ruby中,Integer实际上是一个从不灌输的抽象类。相反,它有两个子类,
Fixnum
Bignum
,数字根据大小自动在它们之间迁移。在MRI和YARV中,Fixnum可以保存31或63位有符号整数(一位用于标记),具体取决于mach的本机字长