2025年1月1日水曜日

С Новым Годом 2025 !

あけましておめでとうございます。

今年は巳年。「古き衣を脱ぎ捨て、蛇は新たに生まれ変わるべし」となるのでしょうか。

 

電卓の敗退と逆襲


過日、Androidスマートフォンの比較的新し目の機種をいじる機会があり、電卓を使ってみたのですが、いや、驚いちゃったねェ。標準でも、一部の関数機能の利用が出来ますが、中でも驚いたのが、階乗の計算能。普通の関数電卓でも、69! までしか計算できませんが、Androidスマートフォンの階乗計算、19515! = 6.758099E75235 というキチガイじみた値まで計算しましたよ。マイッタ。

しかし、階乗の計算に限定すれば、upython でもある程度イケるのではないか、と。
 
 ```
def long_f(n) :
  r =  1
  for i in range(n) :
    r = r * (n+1)
  return r

long_f(1000)
```
これで値を返すはずなのですが、fx-CG50 で行うと、メモリが足りないという返事。これはクルシイ。恐らく、整数の全桁を表示するためのメモリが足りない、という所なのではなかろうか。
この面だけみると、「関数電卓の敗北」という具合になりそうですが、Androidスマートフォンの様に概算で良ければ、それなりの値を得る方法はあります。こんなコードはどうでしょうか。
```
import math

def large_f(n) :
  r =  0
  for i in range(n) :
    r = r + math.log10(i+1)
  print(pow(10, r-int(r)), 'e', int(r))
```
以下、パソコで実行した場合の出力を示しておきます。
```
>>> large_f(330)
2.8240846225829777 e 689
>>> large_f(1000)
4.023872600748676 e 2567
>>> large_f(10000)
2.84625968062148 e 35659
>>> large_f(20000)
1.8192063204524245 e 77337
```

やっている事と云うと、階乗の計算の対数を取ると解ります。log(n!) = Σ log(k) です。総和計算をしてから、10のべき乗にすれば、所望の値を得られるという寸法。

fx-CG50 では、複数の手段が利用できます。以下では、20000! の計算をやってみた結果を示しておきます。

  1. 数式計算

    こんな具合です。
    ```
    Σ(log I, I, 1, 20000) →R 
    77337.25988
    ```
    ほぼ、30秒くらい掛かりました。20000までの対数の和を求めるとなると、これくらいは掛かりそうです。

  2. BASIC
    色々と技巧を凝らす余地がありそうですから、ここではBASICのコードを提示する事は止めておきますが、
    当方が試した所、およそ50秒程度の時間が掛かりました。プログラムループですから、時間が掛かるのはやむを得ない所です。その分、プログラムの内容を変更できるという自由度がある訳です。

  3. upython
    上記のコードがそのまま動きます。
    fx-CG50 upython では、圧倒的な速さで、なんと 6秒くらいでした。

まあ、16000! なんて値、日常で使う機会はなさそうなので、今回も「ネタ」という事で御了承戴き度。

  こうしてみると、upython の可能性は目を見張るものがありますが、これだけに突っ込んでしまうと、関数電卓の部分が疎かになったりしないのか、という不安もあります。
それよりは、様々な計算の手段を充実して、社会に貢献して欲しいと、切に願うものではあります。

そんな具合ですが、今年もポツポツとやって行きたく、よろしくお願い申し上げ候。


6 件のコメント:

Sentaro さんのコメント...

akatuki様、皆様、
明けましておめでとうございます。今年もよろしくお願いいたします。

69!を超えるlogでの階乗計算は昔ポケコンでやってたので懐かしすぎます。
階乗は他にも多倍長計算で全部の桁を計算するっていうのもやってましたけど、計算機的に円周率と並んでいろいろ遊べるネタではありますね。(^^)

>こうしてみると、upython の可能性は目を見張るものがありますが、これだけに突っ込んでしまうと、関数電卓の部分が疎かになったりしないのか、という不安もあります。

通常計算では内部計算精度がBCD15桁なのでPythonの64bit倍精度の方が精度も扱える範囲も広いという状態になってるわけですが、それが故に相互に乗り入れできない壁があるのかもしれませんね。

Pythonだけでも本来の計算機の代わりとしても使えることを考えると、ユーザーにとっては計算方法の選択肢があるのはよいことなのでPython導入も正解だったと言えるでしょう。
あとは不足しているモジュール関連の拡充に期待したいところですね。(^^)

K さんのコメント...

あけましておめでとうございます。

赤字のMemoryError:については、シェルに出力する際の1行当たりの文字数制限があるようで、509桁を超えるとエラーが出ます。詳細は忘れてしまいましたが、他にも文字列を扱う際に700文字程度までしかムリだとか、いろいろあったように記憶しています。

20000!の計算そのものは100秒程度で計算でき、自前の数値解析モジュール(数年前に某雑誌に投稿したもの)を用いて1分程度で桁数を算出し、その後は任意の100桁分を数秒程度で表示、といった感じのノリで扱えました。181920632023...となっていましたので対数を利用した場合だと精度は10桁のようですね。

intについては以前いろいろ試した感じでは数10万桁くらいならなんとか行けるかな、と感じました。pythonのバージョンが3.4相当のままで今となってはもう古くなっちゃっていますけど、基本がpythonなだけに気軽にプログラミングできるのがいいです。シェルの使い勝手と安定性には助かってます。できれば非公式のpythonextra並みに更新してくれればとは思うんですけどね。

akatuki さんのコメント...

Sentaro 様、新年早々の御来訪、誠に恐れ入ります !

遅れてしまい申し訳ない。新年のポストとは言え、年末に準備して、予約投稿としておりましたものですから。

> 69!を超えるlogでの階乗計算は昔ポケコンでやってたので懐かしすぎます。

ですよネ。
当方の場合は、最初に買った関数電卓で限界まで試したものでした。
当時は、関数電卓って、こんなに大きい数まで計算できるのネ、と感銘を覚えたのですが、
それは、今からン十年前 ...

> 階乗は他にも多倍長計算で全部の桁を計算するっていうのもやってましたけど、計算機的に円周率と並んでいろいろ遊べるネタではありますね。(^^)

オオッ、色々と考えるのですね !
確かに、階乗とか円周率計算とか、電卓のBench Mark っぽい所があります。

> 通常計算では内部計算精度がBCD15桁なのでPythonの64bit倍精度の方が精度も扱える範囲も広いという状態になってるわけですが、それが故に相互に乗り入れできない壁があるのかもしれませんね。

そこは、仰るとおりなのでしょう。
一方で、TI, HP 電卓では、結構な大きさの数が計算できた筈で、CASIOとしても、Neon-Generative な所を目指しても ?
と、希なる望みを託したいものではあります。

> Pythonだけでも本来の計算機の代わりとしても使えることを考えると、ユーザーにとっては計算方法の選択肢があるのはよいことなのでPython導入も正解だったと言えるでしょう。

uPython電卓の嚆矢であるNumworks電卓では、通常の電卓部分でプログラム機能が使えない、という具合ですから、
計算と(uPython)プログラミングは「区別」されている様で、そこが、他社の付け入る隙になってくれると面白いかなぁ、なんて思うのでありますが、ガッコの試験対応という側面で、ここがムズカシイ所。

> あとは不足しているモジュール関連の拡充に期待したいところですね。(^^)

CASIO電卓では、特に望まれる所ではあります !
今年は巳年、pythonはニシキヘビ。更なる進展を願いつつ !!

akatuki さんのコメント...

K 様、新年早々の御来訪、誠に恐れ入ります !

> 赤字のMemoryError:については、シェルに出力する際の1行当たりの文字数制限があるようで、509桁を超えるとエラーが出ます。詳細は忘れてしまいましたが、他にも文字列を扱う際に700文字程度までしかムリだとか、いろいろあったように記憶しています。

御教示ありがとうございます。
そうか、限界を確認しておけば、もう少しやりようがあったのですね。

> 20000!の計算そのものは100秒程度で計算でき、自前の数値解析モジュール(数年前に某雑誌に投稿したもの)を用いて1分程度で桁数を算出し、その後は任意の100桁分を数秒程度で表示、といった感じのノリで扱えました。

オオッ ! 「某雑誌に投稿」ですか !!

> 181920632023...となっていましたので対数を利用した場合だと精度は10桁のようですね。

対数の計算は、倍精度浮動小数点数なので、精度は限られますネ。

> intについては以前いろいろ試した感じでは数10万桁くらいならなんとか行けるかな、と感じました。

内部的には計算可能ながらも、出力でメモリが足りないという具合でしたか。

pythonのバージョンが3.4相当のままで今となってはもう古くなっちゃっていますけど、基本がpythonなだけに気軽にプログラミングできるのがいいです。シェルの使い勝手と安定性には助かってます。

仰るように、python REPLを電卓として使う、というのは、python チュートリアルでも述べられておりますネ。
これがかなり使えるので、ガッコの試験では使えなくしているのか ?

> できれば非公式のpythonextra並みに更新してくれればとは思うんですけどね。

コレって、海外有志のuPython イムプリメントでしょうか ?
XCASでもpython モードがありましたから、あっても不思議じゃないのですが、しかし、やるなぁ ...

K さんのコメント...

> コレって、海外有志のuPython イムプリメントでしょうか ?
> XCASでもpython モードがありましたから、あっても不思議じゃないのですが、しかし、やるなぁ ...

サイトを紹介しようかと思ったのですが、去年の暮れには繋がったものの403エラーとなってしまっていました^^; 一時的なサーバーダウンならいいのですが……サブドメインの配布元自体はダウンしていなかったのでリンクを貼っておきます。

Releases - Lephenixnoir/PythonExtra - Forge de Planète Casio
https://git.planet-casio.com/Lephenixnoir/PythonExtra/releases

無理をさせるとフリーズしてハードリセットするハメになってしまったり、一部の文字が入力できないなど使い勝手に難があるものの、micropythonのかなり新し目のバージョン(電卓に実装されているものとして私が知っている中では一番最新)となっていて、キー入力やアニメーションにも対応しているので、けっこう楽しく遊べるかと思います。作者もシェルの改善など前向きなようでしたので、これでしかできないことをたまにやりながら、のんびり待っているところです。

akatuki さんのコメント...

K 様、どうもありがとうございます !

> サイトを紹介しようかと思ったのですが、去年の暮れには繋がったものの403エラーとなってしまっていました^^; 一時的なサーバーダウンならいいのですが……サブドメインの配布元自体はダウンしていなかったのでリンクを貼っておきます。

> Releases - Lephenixnoir/PythonExtra - Forge de Planète Casio
> https://git.planet-casio.com/Lephenixnoir/PythonExtra/releases

早速、ダウンロード致しました。御紹介、有り難く !

> 無理をさせるとフリーズしてハードリセットするハメになってしまったり、一部の文字が入力できないなど使い勝手に難があるものの、micropythonのかなり新し目のバージョン(電卓に実装されているものとして私が知っている中では一番最新)となっていて、キー入力やアニメーションにも対応しているので、けっこう楽しく遊べるかと思います。作者もシェルの改善など前向きなようでしたので、これでしかできないことをたまにやりながら、のんびり待っているところです。

0.3.0 betaとなっておりますが、どうして、大分、機能が盛り込まれている様ですネ !
文書を見た範囲では、電卓内部のAPIを扱える gint module の実装が機能拡張に貢献している様子。
スゴい事を考えるものです ! かなり遊べそうですネ。
当方も、ポツポツと動かして、遊んでみようと思います。

電卓喫茶様が、fx-CG50 の upython は、点を打つとかしか出来ないので、おヌヌメ出来ないとpostしておりました。
CASIO純正 upython がアプデされる前に、こうしたイムプリメントが公開されているので、fx-CG50 user としては、こうしたツールを使いつつ、楽しんで行くのが良いのか、と。