なぜ素数の平方根までチェックして、それが素数かどうかを判断するのですか?


392

数が素数かどうかをテストするために、なぜその数の平方根までしか割り切れないかどうかをテストしなければならないのですか?


33
もし理由n = a*ba <= bその後a*a <= a*b = n
Will Ness、2014年

7
明確にするために、これはまでのみテストする必要があることを意味しfloor(sqrt(n))ます。
Acumenus

回答:


659

数がいる場合nの素数ではない、それは二つの要因に分解することができますab

n = a * b

abの平方根よりも両方大きくすることはできません。nその製品があるため、a * bより大きくなりますsqrt(n) * sqrt(n) = n。したがって、の因数分解でnは、少なくとも1つの因数がの平方根より小さくなければなりません。平方根n以下の因数が見つからない場合はn、素数でなければなりません。


sqrt(n)浮動小数点を使用していることを考えると、このプロパティが保持するのに十分正確でなければなりません。
ブノワ

@Benoît 複雑な浮動小数点数を避けたい場合は、常にチェックi * i <= nを使用できi <= sqrt(n)ます。
Sven Marnach

348

さんが言ってみましょうm = sqrt(n)、その後m × m = n。今場合はn、その後プライムないnように記述することができますn = a × bので、m × m = a × b。お知らせmのに対し、実数でnaかつb自然数です。

これで、3つのケースが可能になります。

  1. a> m⇒b <m
  2. a = m⇒b = m
  3. a <m⇒b> m

すべての3例では、min(a, b) ≤ m。したがって、までm検索すると、の少なくとも1つの因数を見つけることになりn、これはn素数でないことを示すのに十分です。


4
n = 12 m = sqrt(12)= 3.46、a = 2、b =6。n= m mつまり12 = 3.46 * 3.46およびn = a bつまり12 = 2 * 6。ここで、条件3. a <m <bつまり2 <3.46 <6.です。素数をチェックするには、3.46未満の数だけをチェックする必要があります。したがって、nの平方根(n = 4、m = a = b = 2の場合)以下の数で分割可能性を確認します。
anukalp 2014年

2
最初に仮定を強調する必要があると思います。仮定n is not a primeし、それを証明します。そうでなければ、それは素数です。
Huei Tan

実際には、それがより良い答えであるとは思いません。正解ですが、実際の質問には答えません。素数と平方根に関する他のいくつかのダイナミクスについて説明しているだけです。@Svenの回答はどちらも簡潔であり、その過程でこれ以上質問を作成しません。
Jon M

1
私は最後の良いバージョンにロールバックしました。誰かが不必要に単語( 'hence')を削除したときにそれを逃しました。これはフローに必要です。
ネスは

55

因数がnの平方根より大きい場合、それと乗算してnと等しくなる他の因数は必然的にnの平方根よりも小さくなるためです。


37

より直感的な説明は:-

100の平方根は10です。たとえば、aとbのさまざまなペアについて、axb = 100としましょう。

a == bの場合、それらは等しく、正確に100の平方根です。それは10です。

それらの1つが10未満の場合、もう1つは大きくする必要があります。たとえば、5 x 20 == 100です。1つは10より大きく、もう1つは10より小さいです。

axbについて考えると、一方がダウンした場合、もう一方が大きくなって補償する必要があるため、製品は100のままです。平方根を中心に旋回します。

101の平方根は約10.049875621です。したがって、101の素数性をテストする場合、10を含む10までの整数を試すだけで十分です。ただし、8、9、および10は素数ではないため、7までの数だけをテストする必要があります。プライム。

なぜなら、10より大きい数値の1つを持つ因子のペアがある場合、そのペアのもう一方は10未満でなければならないためです。小さい方の因子が存在しない場合、101の大きな因子と一致しません。

121をテストしている場合、平方根は11です。1から11までの素数の整数をテストして、均等に入るかどうかを確認する必要があります。11は11回に入るので、121は素数ではありません。11をテストせずに10で停止した場合、11を逃していたことになります。

奇数のみをテストする場合、2より大きいが平方根以下のすべての素整数をテストする必要があります。

`


3
「axbについて考えると、一方がダウンした場合、もう一方が大きくなって補償する必要があるため、製品は100のままです。平方根を中心に旋回します。」ああ瞬間!ありがとうございました!
ブライアンウィギントン2018

これが最良の答えです。
JeanieJ

19

仮定n素数(1より大きい)ではありません。だから、数字があるab、そのようなことは、

n = ab      (1 < a <= b < n)

関係を乗じてa<=bによってab我々が得ます:

a^2 <= ab
 ab <= b^2

したがって:(n=ab

a^2 <= n <= b^2

したがって:(aおよびでbあることに注意してください)

a <= sqrt(n) <= b

したがって、ある数(1より大きい)が素数ではなく、その数の平方根までの可分性をテストすると、因子の1つが見つかります。


8

与えられた整数Nが素数でないとしましょう、

次いで、Nは二つの要因に因数分解することができるab2 <= a, b < Nその結果N = a*b。明らかに、それらの両方がsqrt(N)同時に大きくなることはできません。

一般性を失うことなく、aより小さいと仮定しましょう。

ここNで、範囲に属する除数が見つからなかった場合[2, sqrt(N)]、それはどういう意味ですか?

これは、N[2, a]asの除数がないことを意味しa <= sqrt(N)ます。

したがって、a = 1そしてb = n、したがって定義により、N素数です

...

満足していない場合の参考資料:

のさまざまな組み合わせ(a, b)が可能です。それらがそうであるとしましょう:

(a 1、b 1)、(a 2、b 2)、(a 3、b 3)、.....、(a k、b k)。一般性を失うことなく、a i <b i、と仮定し1<= i <=kます。

さて、N素数ではないことを示すことができるようにするには、さらにiを因数分解できないことを示すだけで十分です。また、a i <= であることもわかっているため、すべてのa iをカバーsqrt(N)するまでチェックする必要があります。そしてそれゆえ、あなたは素数であるかどうかを結論付けることができるでしょう。sqrt(N)N

...


7

これはすべて、因数分解と平方根の基本的な使用方法にすぎません。

それは抽象的であるように見えるかもしれませんが、実際には、それは単に、素数ではない最大の階乗がその平方根でなければならないという事実に単に基づいています:

sqrroot(n) * sqrroot(n) = n

上記の任意の整数ならば、ということを考える1と、以下のかまでsqrroot(n)均等に分割はn、その後、n素数にすることはできません。

疑似コードの例:

i = 2;

is_prime = true;

while loop (i <= sqrroot(n))
{
  if (n % i == 0)
  {
    is_prime = false;
    exit while;
  }
  ++i;
}

華麗な観察。この観察を使用guardして、この便利なstackoverflow.com/a/25555762/4475605と組み合わせてSwiftでステートメントを作成し、計算能力を浪費するのではなく、計算を早期に終了します。投稿ありがとうございます。
エイドリアン

@エイドリアン私はこの答えに戻った後、あなたの投稿時に間違いを見つけたことを告白しなければなりません。0で除算を行うことはできません。理論的++iには、1になる可能性がある場合、常にfalseを返します(1がすべてに除算されるため)。上記の答えを修正しました。
スーパーキャット

うん...私は私のコードでそれに対処しました...あなたの平方根観測は、計算の実行を開始する前の早い段階で素数以外の値を破棄する優れた方法です。時間の浪費であることが判明した大きな数で殺されていました。また、このアルゴリズムは大きな数の処理時間も大幅に削減できることも学びました。en.wikipedia.org/wiki/Miller –Rabin_primality_test
エイドリアン

6

したがって、数値Nが素数かどうかを確認します。Nが<= SQROOT(N)の数で割り切れるかどうかを確認するだけです。これは、Nを任意の2つの因子に因数分解すると、XとYが発生するためです。N = XY。XとYのそれぞれはSQROOT(N)よりも小さくできません。そのため、X Y <N XおよびYのそれぞれは、SQROOT(N)より大きくできません。

したがって、一方の因子はSQROOT(N)以下でなければなりません(もう一方の因子はSQROOT(N)以上です)。したがって、Nが素数であるかどうかを確認するには、SQROOT(N)以下の数値のみを確認する必要があります。


3

素数ではない「a」という数字があるとします[素数/合成数ではありません-1またはそれ自体以外の数で均等に分割できる数。たとえば、6は、2または3、1または6で均等に分割できます。

6 = 1×6または6 = 2×3

したがって、「a」が素数でない場合は、他の2つの数値で割ることができ、これらの数値が「b」と「c」であるとしましょう。つまり

a = b * c。

ここで、「b」または「c」の場合、いずれも「a」の平方根よりも大きい「「b」の乗算よりも「c」は「a」よりも大きくなります。

したがって、「b」または「c」は常に「=」の平方根であり、「a = b * c」の式を証明します。

上記の理由により、数値が素数かどうかをテストするときは、その数値の平方根までしかチェックしません。


1
b&c <= Math.sqrt(n)?; むしろbである必要があります|| c(bまたはc)。これは、n = 6、b = 3、c = 2の場合、Math.sqrt(n)> cであるためです。
daGo 2018

訂正してくれてありがとう。修正を行います。:)
アブナセルMdショアイブ

2

任意の数が与えられた場合n、その因子を見つける1つの方法は、平方根を求めることですp

sqrt(n) = p

もちろん、それだけで乗算pすると、次のようになりますn

p*p = n

次のように書き直すことができます。

a*b = n

どこp = a = b。場合はa増加し、その後、b維持するために減少a*b = n。したがって、p上限です。

更新:この答えを今日もう一度読み直しましたが、より明確になりました。p整数である場合n、素数ではないため、値は必ずしも整数を意味するわけではありません。したがって、p実数になる可能性があります(つまり、分数付き)。そして、の全範囲を通過する代わりにn、今はの全範囲を通過する必要があるだけですp。もう1つpはミラーコピーであるため、実際には範囲を半分にします。そして、今、私たちは実際にを再実行し、範囲の半分までさらにsquare root実行することができることがわかりましたp


1

nを非素数にします。したがって、1より大きい少なくとも2つの整数係数があります。fをnのそのような係数の最小値とします。f> sqrt nと仮定します。次に、n / fは整数LTE sqrt nであり、fより小さい。したがって、fをnの最小係数にすることはできません。Reductio ad burdum; nの最小係数はLTE sqrt nでなければなりません。


1

すべての合成数は素数の積です。

としましょうn = p1 * p2、どこでp2 > p1、それらは素数です。

その場合n % p1 === 0nは合成数です。

もしそうならn % p2 === 0n % p1 === 0同様に何を推測します!

もしそうならその方法はありませんn % p2 === 0が、n % p1 !== 0同時には。言い換えれば、合成数np2、p3 ... pi(そのより大きい因数)で均等に除算できる 場合、その最小の因数p1でも除算する必要があります。最低の要因p1 <= Math.square(n)は常に真であることがわかります。


なぜそれが本当なのか知りたい場合は、@ LoMaPhが回答で事実を大きく説明しました。他の提供された回答を視覚化して理解するのに本当に苦労したので、私の回答を追加しました。クリックされなかっただけです。
daGo

0

数値nの素数性をテストするには、最初に次のようなループが予想されます。

bool isPrime = true;
for(int i = 2; i < n; i++){
    if(n%i == 0){
        isPrime = false;
        break;
    }
}

上記のループが行うことは次のとおりです。与えられた1 <i <nに対して、n / iが整数かどうかをチェックします(残りは0のままです)。n / iが整数であるiが存在する場合、nが素数でないことを確認できます。その時点でループが終了します。iがない場合、n / iは整数で、nは素数です。

すべてのアルゴリズムと同様に、次のように質問します。

上記のループで何が起こっているのか見てみましょう。

iのシーケンスは次のようになります:i = 2、3、4、...、n-1

そして、整数チェックのシーケンスは次のようになります:j = n / i、つまりn / 2、n / 3、n / 4、...、n /(n-1)

一部のi = aの場合、n / aは整数、n / a = k(整数)

またはn = ak、明らかにn> k> 1(k = 1の場合、a = nですが、nに到達することはありません。k= nの場合、a = 1ですが、フォーム2を開始します)

また、n / k = aであり、前述のとおり、aはiの値なので、n> a> 1です。

したがって、aとkはどちらも1からnまでの整数です(これを含まない)。以来、iはその範囲内のすべての整数に到達するため、ある反復ではi = a、他の反復ではi = kになります。nの素数性テストがmin(a、k)で失敗すると、max(a、k)でも失敗します。したがって、min(a、k)= max(a、k)(2つのチェックが1つに減る)でない限り、これらの2つのケースの1つだけをチェックする必要があります。つまり、a = kで、a * a = n、 a = sqrt(n)を意味します。

つまり、nの素数性テストが一部のi> = sqrt(n)(つまり、max(a、k))で失敗した場合、一部のi <= n(つまり、min(a)でも失敗します。 、k))。したがって、i = 2からsqrt(n)までのテストを実行すれば十分です。


コメントと6歳の回答には、はるかに短く、IMHOがはるかに理解しやすく、よりトピックに関する説明があります...
Thierry Lathuille 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.