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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

4回答

299閲覧

素数を求めるジェネレーター

newyee

総合スコア213

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

0クリップ

投稿2018/09/15 09:35

以下は素数を求めるためのコードとなるのですが、お聞きしたい所がございます。

javascript

1//素数を求めるためのジェネレーター 2function* genPrimes() { 3 let num = 2;//素数の開始位置 4//2から順に素数を判定し、素数の場合にだけyield(無限ループ) 5 while (true) { 6 if (isPrime(num)) { yield num; } 7 num++; 8 } 9} 10//引数valueが素数かどうかを判定 11function isPrime(value) { 12 let prime = true;//素数かどうかを表すフラグ 13//2~Math.sqrt(value)で、valueを割り切れる値があるかを判定 14 for (let i = 2; i <= Math.floor(Math.sqrt(value)); i++) { 15 if (value % i === 0) { 16 prime = false;//割り切れたら素数ではない 17 break; 18 } 19 } 20 return prime; 21} 22 23 24 25for(let value of genPrimes()) { 26//素数が101以上になったら終了 27 if (value > 100) { break; } 28 //console.log(value); 29 30} 31

上記、while文内の「if(isPrime(num))」この部分のnumの値が2から順当に加算されていき「4」が入った時の、処理に関してなのですが、まず、isPrime関数のfor文の条件式がTRUEとなり、次のif文内で、primeがfalseとなり、if文を抜け、for文の繰り返しに戻り、iの値が3となり条件式がfalseとなり、return prime が実行され、while文に戻ります。次にnumの値が、5となりisPrime関数が実行され、primeにtrueが入り、for文が実行されるのですが、この時、iの値が2のままだと、primeの値がfalseとなってしまいます。iの値が、numの値が4だった時の3のまま継続されるということはないと思うのですが、このままだと素数であるはずの5が返らないということになってしまいます。
この点に関しまして、どうしても理解できないため、ご解説の方お願いしたいです。

DrqYuto👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/09/15 09:50

すみませんが、ごちゃごちゃ書かれてて何を聞きたいのか分かりません。もう少し整理してもらえますか?
guest

回答4

0

この時、iの値が2のままだと、primeの値がfalseとなってしまいます。

なりません。5は2で割り切れません。

投稿2018/09/15 09:49

maisumakun

総合スコア145121

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

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

newyee

2018/09/15 10:08

numが5であり、iの値が2のままですと、Math.floor(Math.sqrt(value))こちらの処理においてvalueの値は2となり、namが4の時と同じ処理がなされてしまうんですよね...
maisumakun

2018/09/15 10:09

valueの値は2となり「ません」。Math.sqrt(value)としてもvalueは変化しません。
newyee

2018/09/15 10:17

試しに、「var a = 5;」「a = Math.floor(Math.sqrt(a));」としてみて、「a」の値を出力してみましたら、2となったのですが、valueの値が変化しないとはどういうことなのでしょうか?
maisumakun

2018/09/15 10:19

それは、「a=(略)」で代入しているから変化しているだけです。元のコードでは、Math.floor(Math.sqrt(value))を代入していませんので、valueが変化する余地はありません。
yukihisa

2018/09/15 10:20

aを計算して再代入したらそりゃ2になるでしょ。。。 今回は i=Math.floor(Math.sqrt(value));なんだからvalueは変化しませんよ。
newyee

2018/09/15 10:30

あ、代入されているわけではないので、変化しないということだったんですね... 基本的なことが分かってなかったです... しかし、「 i=Math.floor(Math.sqrt(value));」ではなく、「i <= Math.floor(Math.sqrt(value))」となっており、代入されている訳ではないという所で、「i <= Math.floor(Math.sqrt(value))」ここの部分の条件式が何を意味しているのかがいまいち分からないんですよね...
yukihisa

2018/09/15 11:03 編集

簡単に書くと「i * i <= value」ということです。 たとえばnum=11で考えると、3*3=9、4*4=16なので「i=3」まで計算するという形ですが、 11まで素数を探すときは2*[2,3,4,5]、3*[2,3]という形で、4以降は2、3の時の組み合わせを繰り返すだけなので平方根以下、というくくりなのです。 …小難しくなった@@;
newyee

2018/09/15 10:50

ご解説ありがとうございます。 自分の理解が悪いため、完全とにではないのですが、おおまかに理解できた気がします!
guest

0

理解なさったようですが、どうしても気になるので。

まず、isPrime関数のfor文の条件式がTRUEとなり、次のif文内で、primeがfalseとなり、if文を抜け、for文の繰り返しに戻り、iの値が3となり条件式がfalseとなり、return prime が実行され、while文に戻ります。

ここのところ明らかに間違っています。breakのことを考えておられません。
「isPrime関数のfor文の条件式がTRUEとなり、次のif文内で、primeがfalseとなり、if文を抜け、」とのことですが、primeがfalseになる次の行でbreakが起こり、forを抜け、直ちにreturn false;となります。iは3にはなりません。

-- 蛇足

条件式の中で「Math.floor(Math.sqrt(value))」ここの部分に2つの関数を通す意味はなんなのでしょうか?valueの値が変化していないのだとしたら、関数を通すいみはないように思えてしまうんですよね

条件判定のために、関数にかけています。またvalueを変えないままiがvalueの平方根を切り捨てした値以下であるか比較するために、わざとvalueを変化させずに比較しているのです。

しかしながら

javascript

1function isPrime(value) { 2//2~Math.sqrt(value)で、valueを割り切れる値があるかを判定 3 let ceiling = Math.floor(Math.sqrt(value)); 4 for (let i = 2; i <= ceiling; i++) { 5 if (value % i === 0) { 6 return false; 7 } 8 } 9 return true; 10}

というように一旦他の変数(ceiling)に受けることは可能なので、「なんでこうなっているか」は、究極的にはこのコードを書いた人に聞くしかないでしょうね。

投稿2018/09/18 14:45

papinianus

総合スコア12705

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

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

0

math

1//value % i 25%2=1

ですよ……

ちなみに、for (let i = 2; i <= Math.floor(Math.sqrt(value)); i++) の部分はこのループに入る際に let i = 2 で i を初期化しているため、次回の isPrime() 呼び出しで値が引き継がれることはありません。

投稿2018/09/15 10:12

R.Mizukami

総合スコア1077

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

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

newyee

2018/09/15 11:43

ご回答頂いた部分でどうしてもお聞きしたいことがあるのですが、「for (let i = 2; i <= Math.floor(Math.sqrt(value)); i++)」この部分の、「i <= Math.floor(Math.sqrt(value));」ここの条件式において、「Math.floor(Math.sqrt(value))」ここの「value」の値は、Math.sqrt及びMath.floor関数によって、変化していると思っていたのですが、他の方からもご指摘を受けたのですが、変化していないとのことでした。 そうなりますと、仮に、valueの値が5だった場合、条件式の中で「Math.floor(Math.sqrt(value))」ここの部分に2つの関数を通す意味はなんなのでしょうか?valueの値が変化していないのだとしたら、関数を通すいみはないように思えてしまうんですよね...
guest

0

動かしてみましたが問題なかったです。
「2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97」
が選択されましたよ。

追記

素数計算
提示のソースそのままで表示部のみ追加した形です。
リンククリックすると97まで素数を表示しますよ。

投稿2018/09/15 10:02

編集2018/09/15 10:38
yukihisa

総合スコア672

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問