[ruby-list:50950] Re: 整数同士の乗数を求めるとComplexになるのはなぜでしょうか

From: 大城 尚紀 <n-oshiro@...>
Date: 2022-05-21 13:17:35 UTC
List: ruby-list #50950
下田さん、こんにちは。大城と申します。

(昨日送信したのですが、メールアドレス違いで投稿できていなかったようです。Sekiさんからも同様のご指摘きていますが、再送致します。)

ちょっと見てみました。途中で出てくるRationalの値が次の段階で「負数の小数乗」になって、複素数となるようです。ですので、整数同士の乗数の演算ではありません。

first=2, prev=1,
last=3から始めて、cur=prev**last+prev+1=1**3+1+1=1+1+1で3。更新して、prev-=cur,
last=curで、prev=-2,
last=3となって、この段階でcur=-9になります。curが負数なので判定はなしですが、更新して、prev-=curで7,
last=-9になります。

このprev=7; last=-9 の状況で、curを求めると
cur=prev**last+prev+1=7**(-9)+7+1ですが、始めのマイナス乗の段階で逆数になって7**(-9)で1/40353607のRationalになります(微小値)。さらに(+7+1)の8となる加算をして322828857/40353607
となり、これが表示されています。

この
322828857/40353607は、実数にして小数点以下を求めてみると8.00000002478093となります。この段階で整数でなくなっています(また、ざっくり8だったとしても素数でもないので、算出式か判定が誤っているかもしれません)。

それで、次の更新で、prev -= cur で
-1.00…2478…(負数)、last=curで8.000…2478…(小数点以下の情報あり)になって、prev**lastの演算を行うと(-1.00…)**8.000…2478で、実質√(-1)のような形になって複素数になるようです。(-1)**(0.000000025)というような状況です。

curを8に近い値(小数点以下が発生する値)として、以下のように80/11としても同様に複素数になります(Rationalであっても、もし80/10であれば更新値は1/1として複素数にならずに求まります)。

 prev = 7; last = -9; cur = Rational(80, 11)
 prev -= cur; last = cur
 print("#{prev} #{last} #{prev**last}\n") # -3/11 80/11
-5.156520268369788e-05-5.950941621574082e-05i

上記のcurの設定箇所をRational(80,11).to_fとして、実数にしても同様に複素数になります。


2022年5月20日(金) 17:04 Jun'ya Shimoda <junshimo2@gmail.com>:

> 下田と申します。
> 今、確実に素数を求めるプログラムを作ろうと頑張ってます。
> 添付ファイルがプログラムです。
>
> ruby ./mk_prime.rb
> で実行すると
> 「3は素数
> 322828857/40353607は素数
> ./mk_prime.rb:37:in `to_i': can't convert
> 1.00000017346654+7.785160984669524e-08i into Integer (RangeError)]」
>
> というエラーになるんです。
> 整数しか扱ってないプログラムなのに
> Complexになる理由が分かりません。
>
> よろしくお願いします。
>
>

In This Thread

Prev Next