目次

計算精度

n! を例にして

変数の型にはそれぞれ扱える値の上限がありますが、精度にも上限があります。この上限が何を意味するのか実際に見てみましょう。

値の上限(最大値)

まず、intで扱える最大値は 2147483647 なので、479001600(=12!)に13をかけると(これが13!)、この上限を超えます。このときなぜエラーにならず間違った答がでるかはともかく、12!まで正しく計算できます。

longでは 9223372036854775807 が上限ですから、20!=2432902008176640000 までを正しく計算できます。

double ではもっと先まで計算できますが、細かなところで誤差が出ています。( doubleで計算すると大きな値の表示が 3.99168E7 のように E 付きの表示になりますが、真の値との比較のため書き直しています)

いろいろな型の変数をつかった n の階乗

nintで計算longで計算doubleで計算真の値
11111
22222
36666
424242424
5120120120120
6720720720720
75040504050405040
840320403204032040320
9362880362880362880362880
103628800362880036288003628800
1139916800399168003991680039916800
12479001600479001600479001600479001600
131932053504622702080062270208006227020800
141278945280871782912008717829120087178291200
152004310016130767436800013076743680001307674368000
162004189184209227898880002092278988800020922789888000
17-288522240355687428096000355687428096000355687428096000
18-898433024640237370572800064023737057280006402373705728000
19109641728121645100408832000121645100408832000121645100408832000
20-2102132736243290200817664000024329020081766400002432902008176640000
21-1195114496-42492900494192148485109094217170944000051090942171709440000
22-522715136-125066071867496857611240007277776077000001124000727777607680000
2386245376081282916178948259842585201673888498000000025852016738884976640000

背景色のある所は正しくない部分です。

精度の上限

double についてだけもう少し大きな n まで見てみると、次のようになります。

つまり double では最初の16桁までは計算してそれ以降は計算していないのです。これが計算精度(計算の細かさ・正確さ)の上限です。double は long より大きな数を扱うことができますが、その代わり計算精度を犠牲にしているわけです。

doubleの計算と真の値との差

ndoubleで計算真の値
24620448401733239400000000620448401733239439360000
251551121004333098600000000015511210043330985984000000
26403291461126605650000000000403291461126605635584000000
271088886945041835200000000000010888869450418352160768000000
28304888344611713840000000000000304888344611713860501504000000
2988417619937397010000000000000008841761993739701954543616000000
30265252859812191030000000000000000265252859812191058636308480000000
3182228386541779220000000000000000008222838654177922817725562880000000
32263130836933693500000000000000000000263130836933693530167218012160000000
3386833176188118860000000000000000000008683317618811886495518194401280000000
34295232799039604120000000000000000000000295232799039604140847618609643520000000
351033314796638614400000000000000000000000010333147966386144929666651337523200000000
36371993326789901200000000000000000000000000371993326789901217467999448150835200000000
371376375309122634300000000000000000000000000013763753091226345046315979581580902400000000
38523022617466601000000000000000000000000000000523022617466601111760007224100074291200000000
392039788208119744200000000000000000000000000000020397882081197443358640281739902897356800000000
40815915283247897700000000000000000000000000000000815915283247897734345611269596115894272000000000

double では大きな値は 39916800 となるところを 3.99168E7 と表します。これはもちろん長くならないようにとか、0 がやたら多いと読めないということもありますが、8の後の00の部分が本当に00かどうかは計算していないというのも理由のひとつです。

double の上限(最大値)

bouble にも扱える数の最大値があります。それは E の後の数が int のように上限があるからです。

ただし、int や long のように間違った値になるのではなく、Infinity(無限大) となって計算を続けます。もちろん Infinity を2倍しても Infinity ですから、計算が正しいわけではありませんが。

doubleの限界

n double     真の値
1604.714723635992059E284471472363599206132240694321176194377951192623045460204976904578317542573467421580346978030238114995699562728104819596262106947389303901748942909887857509625114880781313585012959529941660203611234871833992565791817698209861793313332044734813700096000000000000000000000000000000000000000
1617.590705053947215E28675907050539472187290751785709367294850142012310319093001281637109124354328254874435863462868336514307629599224875954998199218529677928181579808491945059049643495805791487187086484320607292781408814365272803092482649411787748723446459202305005715456000000000000000000000000000000000000000
1621.2296942187394488E28912296942187394494341101789284917501765723005994271693066207625211678145401177289658609880984670515317835995074429904709708273401807824365415928975695099566042246320538220924308010459938381430588227927174194100982189204709615293198326390773410925903872000000000000000000000000000000000000000
1632.0044015765453015E2912004401576545302577599591653441552787812849977066285969791842909503537700391898214353410600501293996807267197132074467682448564494675371562796423038301229264886150247730010662205704969956173185881152129393638460096840367667292791327201696065980922331136000000000000000000000000000000000000000
1643.2872185855342945E293328721858553429622726333031164414657201307396238870899045862237158580182864271307153959338482212215476391820329660212699921564577126760936298613378281401599441328640627721748601735615072812402484508949220556707455881820297436017777661078154820871262306304000000000000000000000000000000000000000
1655.423910666131586E29554239106661315887749844950142128418438215720379413698342567269131165730172604765680403290849565015553604650354393935095487058155225915554489271207416431263907819225703574088519286376487014046409943976621391856730220500349076942933314077895545443758280540160000000000000000000000000000000000000000
1669.003691705778433E2979003691705778437366474261723593317460743809582982673924866166675773511208652391102946946281027792581898371958829393225850851653767501982045219020431127589808697991466793298694201538496844331704050700119151048217216603057946772526930136930660543663874569666560000000000000000000000000000000000000000
1671.5036165148649983E3001503616514864999040201201707840084015944216200358106545452649834854176371844949314192140028931641361177028117124508668717092226179172831001551576411998307498052564574954480881931656928973003394576466919898225052275172710677111011997332867420310791867053134315520000000000000000000000000000000000000000
1682.526075744973197E302252607574497319838753801886917134114678628321660161899636045172255501630469951484784279524860515748677740723676917456344471493998101035608260664837215715659672830848592352788164518364067464570288846442542901808782229015393754650015551921726612213033664926565007360000000000000000000000000000000000000000
1694.2690680090047027E30442690680090047052749392518888995665380688186360567361038491634111179775549421800928543239701427161526538182301399050122215682485679075017796052357489455946484708413412107621199803603527401512378815048789750405684196703601544535852628274771797464002689372589486243840000000000000000000000000000000000000000
1707.257415615307994E3067257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000
171Infinity1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000
172Infinity213455108077438865629072570145733886730056159330291227886899710221263324938130981514753340236723864719151973034287306573083301055694802251980973629541579310661401455397074590303866009781148657954570396550703618437210885875866741044575478989978191912006970522334798649753600000000000000000000000000000000000000000

真の値はどうやって計算したのか

いちばん大きな値を計算できるdoubleに限界があるならどうやって真の値を計算したのでしょうか。いろいろな方法があるのですが、javaには大きな数を計算するための「クラス」が用意されています。これは基本的な変数の型ではありませんが、あたかもBigDecimalという型の変数があるかのように使えるのがjavaです。

詳しい説明は授業が進めば見えてきます。

import java.math.*;
public class Kaijou2 { 
    public static void main( String[] args ) {
       int n = 172;
       BigDecimal s = new BigDecimal("1");
       for( int i=1; i<=n; i++ ) {
           s = s.multiply( BigDecimal.valueOf(i) );
           System.out.print( i );
           System.out.print( "! = " );
           System.out.println( s );
       }
    }
}
もくじ

聖愛高等学校
http://www.seiai.ed.jp/
Last Modified