mač*_*ček 5 ruby math bignum arbitrary-precision
Ruby怎么做到这一点?Jörg或其他任何人都知道幕后发生了什么吗?
不幸的是我不太了解C,所以bignum.c
对我没什么帮助.我有点好奇,有人可以用简单的英语解释它使用的奇迹算法背后的理论.
irb(main):001:0> 999**999
Run Code Online (Sandbox Code Playgroud)
368063488259223267894700840060521865838338232037353204655959621437025609300472231530103873614505175218691345257589896391130393189447969771645832382192366076536631132001776175977932178658703660778465765811830827876982014124022948671975678131724958064427949902810498973271030787716781467419524180040734398996952930832508934116945966120176735120823151959779536852290090377452502236990839453416790640456116471139751546750048602189291028640970574762600185950226138244530187489211615864021135312077912018844630780307462205252807737757672094320692373101032517459518497524015120165166724189816766397247824175394802028228160027100623998873667435799073054618906855460488351426611310634023489044291860510352301912426608488807462312126590206830413782664554260411266378866626653755763627796569082931785645600816236891168141774993267488171702172191072731069216881668294625679492696148976999868715671440874206427212056717373099639711168901197440416590226524192782842896415414611688187391232048327738965820265934093108172054875188246591760877131657895633586576611857277011782497943522945011248430439201297015119468730712364007639373910811953430309476832453230123996750235710787086641070310288725389595138936784715274150426495416196669832679980253436807864187160054589045664027158817958549374490512399055448819148487049363674611664609890030088549591992466360050042566270348330911795487647045949301286614658650071299695652245266080672989921799342509291635330827874264789587306974472327718704306352445925996155619153783913237212716010410294999877569745287353422903443387562746452522860420416689019732913798073773281533570910205207767157128174184873357050830752777900041943256738499067821488421053870869022738698816059810579221002560882999884763252161747566893835178558961142349304466506402373556318707175710866983035313122068321102457824112014969387225476259342872866363550383840720010832906695360553556647545295849966279980830561242960013654529514995113584909050813015198928283202189194615501403435553060147713139766323195743324848047347575473228198492343231496580885057330510949058490527738662697480293583612233134502078182014347192522391449087738579081585795613547198599661273567662441490401862839817822686573112998663038868314974259766039340894024308383451039874674061160538242392803580758232755749310843694194787991556647907091849600704712003371103926967137408125713631396699343733288014254084819379380555174777020843568689927348949484201042595271932630685747613835385434424807024615161848223715989797178155169951121052285149157137697718850449708843330475301440373094611119631361702936342263219382793996895988331701890693689862459020775599439506870005130750427949747071390095256759203426671803377068109744629909769176319526837824364926844730545524646494321826241925107158040561607706364484910978348669388142016838792902926158979355432483611517588605967745393958061959024834251565197963477521095821435651996730128376734574843289089682710350244222290017891280419782767803785277960834729869249991658417000499998999
Jör*_*tag 18
简单:从一年级开始,它就像你一样.除了它不在基数10中计算,它计算基数为40亿(并且变化).
想想看:与我们的数字系统,我们只能表示数字0
来9
.那么,我们如何计算6+7
而不会溢出?易:我们做实际溢出!我们不能将结果表示6+7
为0
和之间的数字9
,但我们可以溢出到下一个位置并将其表示为和之间的两个数字:3×10 0 + 1×10 1.如果要添加两个数字,则从右侧以数字方式添加它们,并向左添加溢出("进位").如果要将两个数相乘,则必须将一个数字的每个数字分别乘以另一个数字,然后将中间结果相加.0
9
BigNum算术(这是通常调用数字大于本机数的这种算法)基本上以相同的方式工作.除了基数不是10,它不是2,它是 - 它是本机整数的大小.因此,在32位机器上,它将是2 32或4 294 967 296.
具体来说,在Ruby Integer
中实际上是一个永远不会被侮辱的抽象类.相反,它有两个子类,Fixnum
并且Bignum
数字在它们之间自动迁移,具体取决于它们的大小.在MRI和YARV中,Fixnum可以保存31或63位有符号整数(一位用于标记),具体取决于机器的本机字大小.在JRuby中,Fixnum可以保存完整的64位有符号整数,即使在32位机器上也是如此.
最简单的操作是添加两个数字.如果你看一下YARV的bignum.c的实现,+
或者更确切地说,bigadd_core
在YARV的bignum.c中实现它,并不是太糟糕.我也读不了C,但是你可以清楚地看到它是如何在各个数字上循环的.