質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1115閲覧

(2^((2^(519-1))-1))*(2-(2^-10889035741470030830827987437816582766072))の正しい計算結果が知りたいです。

GAMEKUN

総合スコア3

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/11/11 05:39

編集2022/11/12 16:49

前提

巨大な値の計算をPythonで行ってみました。

実現したいこと

ideoneのPyPy 2.7.13のdecimalで
(2^((2^(519-1))-1))*(2-(2^-10889035741470030830827987437816582766072))
を計算してみましたが、途中で誤差が出て正しい値が出力されているのか分かりません。
正しい値を知りたいです。先頭100桁とE+ほにゃららで構いません。
ちなみに桁数が10^156ありますので、Python3.10.8やGoogleColabのdecimalでは桁数の桁数が18桁までなので計算できません。
ideoneのPyPy 2では桁数が10^10^5程度までは扱えるようです。(が、一部で誤差が出る。そのためにPython3では桁数制限がかかっていると思われる。)
よろしくお願いいたします。

8.438485139005238033716204113978142132776783207915429197719643649741250839391892405849510296078232762E+258313751232903212140244172706732768962283773495639777019746650509389263410185892774365178070439343478843471144414568958296922314778842870932034756007552127
で正しいかどうかを知りたいわけです。

発生している問題・エラーメッセージ

途中の計算結果:

0E-1000000098

該当のソースコード

https://ideone.com/EdqQxN

Python

1#(2^((2^(w-1))-1))*(2-(2^-t)) 2#2^128倍精度 3#(2^((2^(519-1))-1))*(2-(2^-10889035741470030830827987437816582766072)) 4from decimal import * 5getcontext().prec = 100 6from decimal import localcontext 7with localcontext() as ctx: 8 print(ctx.Emax) # デフォルトの指数上限は999999なので、今回の計算だと足りない 9 ctx.Emax = 10**10**5 # 指数上限を増やす 10 #指数部 11 w = 519 12 #仮数部 13 t = 10889035741470030830827987437816582766072 14 a = ctx.power(2,(w - 1)) 15 b = ctx.power(2,(a - 1)) 16 print(b) 17 c = t * -1 18 d = ctx.power(2,c) 19 print(d) 20 e = (b * 2 - b * d) 21 #最大値 22 print("最大値") 23 print(e) 24 #必要に応じて有効桁を調整する 25 format_str = "{:.1e}".format(e) 26 print(format_str) 27 f = e.log10() 28 #桁数-1 29# print("桁数-1") 30# print(f.quantize(Decimal('0'), rounding=ROUND_FLOOR)) 31 #桁数 32# print("桁数") 33# print(f.quantize(Decimal('0'), rounding=ROUND_CEILING)) 34 g = f.log10() 35 #桁数の桁数-1 36# print("桁数の桁数-1") 37# print(g.quantize(Decimal('0'), rounding=ROUND_FLOOR)) 38 #ウルフラムアルファ確認用 39 print("ウルフラムアルファ確認用") 40 print(g) 41 h = ctx.power(2,t) 42 i = h.log10() 43 #有効桁数 44 print("有効桁数") 45 print(i.quantize(Decimal('0'), rounding=ROUND_FLOOR)) 46

Python+mpmath+gmpy2

1#2^128倍精度 2#(2^((2^(519-1))-1))*(2-(2^-10889035741470030830827987437816582766072)) 3from mpmath import * 4mp.dps = 1000000 5(mpf(2)**((mpf(2)**(mpf(519)-mpf(1)))-mpf(1)))*(mpf(2)-(mpf(2)**mpf(-10889035741470030830827987437816582766072))) 6

試したこと

Python3.10.8(VSCode)やGoogleColabではdecimalでは桁数の桁数が18桁までなので計算できません。
mpmath+gmpy2でも計算してみましたが、dpsが100000まで程度では値の先頭の方、桁数ともに誤差が出て、正しい値がはっきりしません。dpsを1000000にしたら結果がコンソールからはみ出て値の先頭の方が確認できませんでした。また桁数の値がPyPy 2の場合と相違しました。

Python+mpmath+gmpy2でdps = 100の場合

Python+mpmath+gmpy2

1>>> from mpmath import * 2>>> mp.dps = 100 3>>> (mpf(2)**((mpf(2)**(mpf(519)-mpf(1)))-mpf(1)))*(mpf(2)-(mpf(2)**mpf(-10889035741470030830827987437816582766072))) 4mpf('1.738741545572851906007851776954032208812769161318139539364439351610202064301416872947694837078743209829e+258313751232903212140244172706732768962283773495639777019746650509389263410185892774365178070439343470463409842392677007886631633129570799399839688363235724') 5

Python+mpmath+gmpy2でdps = 1000の場合

Python+mpmath+gmpy2

1>>> from mpmath import * 2>>> mp.dps = 1000 3>>> (mpf(2)**((mpf(2)**(mpf(519)-mpf(1)))-mpf(1)))*(mpf(2)-(mpf(2)**mpf(-10889035741470030830827987437816582766072))) 4mpf('8.693707727864259530039258884770161044063845806590697696822196758051010321507084364738474185393716049143428269592664416299506985821607020224451757384081772736694085185953261476092256949585533792382065398255366123346945632455365114496387996812763405070547543636242943582509351695964148881539829278098776930760208512040241459131050857534909186967359333680690876095696574392978402776982242910476888722508873652625966431429199319419162400479389670802250530127697191701685799046457340098916039874145467184794888167675164383011930352737537848617171247730837116311290657456022018847615163555388577340388773985857825851948069000990304471913408925992764573057043682223975592937342873908916124950471446485565735968453329290029508092694774450347618896698260229705612494938176332564765641437441682011291579724298194210916645951676005349723798753644015878111182523064775510486058470694029884469024542601898715230728898371787332915920789625287283111060329377477628692626381070127590574256433161812199884160657947907722e+258313751232903212140244172706732768962283773495639777019746650509389263410185892774365178070439343470463409842392677007886631633129570799399839688363235723') 5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

真っ正直に計算しようとするのが戦略ミスではないかと思います。

まず、x = 2**518y=10889035741470030830827987437816582766072と置いて、2**(x-1)*(2-2**(-y))に分配の法則を適用すれば、2**x - 2**(x - 1 - y)と変形できます。この第2項は第1項より1e-100倍よりもさらに小さな値なので、上100桁だけ求める場面では無視できます。

あとは、2**xの桁数と上位100桁を求める演算に専念すればいい、ということになります。

投稿2022/11/11 06:41

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2022/11/11 06:48

それでも真っ正直に計算させられる値ではありませんので、数学的発想で割り出していく必要があります。
GAMEKUN

2022/11/11 13:07

回答ありがとうございます。 ideoneのPyPy 2.7.13のdecimalではかろうじて計算できたので、その値が合っているかどうか他の方法で計算できないかと質問しました。 引きつづき回答を募集いたします。
guest

0

ベストアンサー

2^x = 10^(log10(2^x)) = 10^(x log10(2)) と変形して計算する。
このべき乗中のx log10(2)の整数部は、指数表記の右側そのものなので、べき乗計算からとりのぞける。
x=2^518 (なお、2^-10889035741470030830827987437816582766072の項は、1の位が繰り下がる程度の影響なので、無視した)で、(x^518)log10(2)は整数部が160桁くらいあるので、上位100桁ほしいなら、計算精度は300桁分くらいは要るはず。

python

1log10_2 = Decimal(2).log10() 2v = (2**518)*log10_2 3print( 10**(v-int(v)), "e", int(v) )

結果:8.69370772786425953003925888477016104406384580659069769682219675805101(略) e 258313751232903212140244172706732768962283773495639777019746650509389263410185892774365178070439343470463409842392677007886631633129570799399839688363235723

投稿2022/11/11 13:48

matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GAMEKUN

2022/11/11 14:41

Python+mpmath+gmpy2でdps = 1000の場合と一致していますね。 こちらが正しかったようです。 ideoneのPyPy 2.7.13のdecimalでは誤差が出ていたようです。 どうもありがとうございます。
GAMEKUN

2022/11/11 14:43

ideoneのPyPy 2.7.13のdecimalでもgetcontext().prec = 1000にしたら正確な値が出ました。
GAMEKUN

2022/11/12 07:49

教えていただいたプログラムは、 ``` from decimal import * getcontext().prec = 1000 from decimal import localcontext with localcontext() as ctx: log10_2 = Decimal(2).log10() v = (2**518)*log10_2 print( 10**(v-int(v)), "e", int(v) ) ``` でやってみたところ、844桁から誤差が出ました。 getcontext().prec = 10000 とすると少なくとも1000桁程度は問題がないようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問