R では、factorial(100) が prod(1:100) と異なって表示されるのはなぜですか? 質問する

R では、factorial(100) が prod(1:100) と異なって表示されるのはなぜですか? 質問する

RIでは説明できない奇妙な動作がいくつか見つかりました。ここで説明できる人がいることを願っています。100の値はこれだと思います。大きな数字

予想される動作を示すコンソールからの数行...

>factorial( 10 )
[1] 3628800
>prod( 1:10 )
[1] 3628800
> prod( as.double(1:10) )
[1] 3628800
> cumprod( 1:10 )
[1]       1       2       6      24     120     720    5040   40320  362880 3628800

しかし、100! を試みると、次のようになります (結果の数字が約 14 桁目から変化し始めることに注意してください)。

> options(scipen=200) #set so the whole number shows in the output
> factorial(100)
[1] 93326215443942248650123855988187884417589065162466533279019703073787172439798159584162769794613566466294295348586598751018383869128892469242002299597101203456
> prod(1:100)
[1] 93326215443944102188325606108575267240944254854960571509166910400407995064242937148632694030450512898042989296944474898258737204311236641477561877016501813248
> prod( as.double(1:100) )
[1] 93326215443944150965646704795953882578400970373184098831012889540582227238570431295066113089288327277825849664006524270554535976289719382852181865895959724032
> all.equal( prod(1:100) , factorial(100) , prod( as.double(1:100) ) )
[1] TRUE

変数を「既知の」数値 100 に設定してテストを実行すると、次のようになります。

# This is (as far as I know) the 'true' value of 100!
> n<- as.double(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000)
> factorial(100) - n
[1] -1902315522848807765998160811905210717565551993186466795054798772271710903343294674760811531554315419925519536152107160826913610179566298858520576
> prod(1:100) - n
[1] -48777321098687378615337456715518223527321845979140174232174327494146433419058837814379782860367062049372295798771978482741374619988879457910784
> prod(as.double(1:100)) - n
[1] 0

最終結果はゼロと評価されますが、変数が100! の値に設定されているかprod( as.double( 1:100 ) )どうかは正しく評価されているにもかかわらず、返される数値は期待どおりに表示されません。prod( as.double( 1:100 ) ) - nn

どなたかこの動作を説明していただけませんか? 私が知る限り、x64 システムを使用しているため、オーバーフローなどとは関係ないはずです。バージョンとマシン情報は以下の通りです。

> .Machine$double.xmax
[1] 1.798e+308
> str( R.Version() )
List of 14
 $ platform      : chr "x86_64-apple-darwin9.8.0"
 $ arch          : chr "x86_64"
 $ os            : chr "darwin9.8.0"
 $ system        : chr "x86_64, darwin9.8.0"
 $ status        : chr ""
 $ major         : chr "2"
 $ minor         : chr "15.2"
 $ year          : chr "2012"
 $ month         : chr "10"
 $ day           : chr "26"
 $ svn rev       : chr "61015"
 $ language      : chr "R"
 $ version.string: chr "R version 2.15.2 (2012-10-26)"
 $ nickname      : chr "Trick or Treat"

誰かこれを説明してくれませんか?Rがすべてを正しく行うことに疑いはありませんし、これはおそらくuseRに関連しています。prod( as.double( 1:100 ) ) - n正しく評価するので何を気にするのかと指摘するかもしれませんが、私はプロジェクト オイラー 問題20そのため、正しい数字を表示する必要がありました。

ありがとう

ベストアンサー1

これは a の最大値ではなくdouble、その精度に関係します。

100!有効桁数 (10 進数) は 158 桁です。IEEE double(64 ビット) には仮数部用の記憶領域が 52 ビットあるため、精度が 16 桁を超えると丸め誤差が発生します。

ちなみに、100!あなたが予想した通り、

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

それで全てR が計算した値が正しくありません。

R についてはよくわかりませんが、比較する前にall.equal()これら 3 つの値すべてをfloats に変換するため、その違いは失われるようです。

おすすめ記事