рдХрд┐рд╕реА рднреА рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╕рднреА рдЕрдкрд░рд╛рдзреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдкреНрд░рд╕рд┐рджреНрдз рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо Eratosthenes рдХреА рдЪрд▓рдиреА рд╣реИ ред рдпрджрд┐ рдпрд╣ рдмрдбрд╝реЗ рдХрд░реАрдиреЗ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рдП рддреЛ рдпрд╣ рдЕрд░рдмреЛрдВ рддрдХ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╢рд╛рдпрдж рджрд╕рд┐рдпреЛрдВ рдЕрд░рдмреЛрдВ рддрдХред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рд░ рдХреЛрдИ рдЬреЛ рдкреНрд░рд╛рдЗрдо рдирдВрдмрд░реЛрдВ рдХреЗ рд╕рд╛рде рдорд╕реНрддреА рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реИ, рд╡рд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╣рдореЗрд╢рд╛ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рд╕рдВрднрд╡ рд╣реИред рдПрдХ рдмрд╛рд░, рд╣реИрдХрд░реНрд░реИрдВрдХ рдкрд░ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдПрдХ рд╕реМ рдмрд┐рд▓рд┐рдпрди рддрдХ рдХреЗ рдЗрди-рдореЗрдореЛрд░реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рдореЗрдореЛрд░реА рджреНрд╡рд╛рд░рд╛ рдЕрдзрд┐рдХрддрдо рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде, рдЕрдЧрд░ рдЗрд░реЗрдЯреЛрд╕реНрдердиреАрдЬ рдХреА рдЫрд▓рдиреА рдереЛрдбрд╝реА рд╕реА рд╕рд░рдгреА рдХреЗ рд╕рд╛рде рд╡рд┐рд╖рдо рд╕рдВрдЦреНрдпрд╛рдПрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреА рд╣реИ, рддреЛ рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ рд▓рдЧрднрдЧ 6 рдЧреАрдЧрд╛рдмрд╛рдЗрдЯ рд╣реЛрдЧрд╛, рдЬреЛ рдореЗрд░реЗ рд▓реИрдкрдЯреЙрдк рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рдерд╛ред рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдПрдХ рд╕рдВрд╢реЛрдзрди рд╣реИ рдЬреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рдмрд╣реБрдд рдХрдо рдорд╛рдВрдЧ рд╣реИ (рд╕рдВрдЦреНрдпрд╛ рдХреА рдореВрд▓ рд╢реНрд░реЗрдгреА рдХреЛ рдХрдИ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдФрд░ рдПрдХ рд╕рдордп рдореЗрдВ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд░рдирд╛) -рдПрд░рд╛рдЯреЛрд╕реНрдердиреАрдЬ рдХреА рдЦрдВрдбрд┐рдд рдЫрд▓рдиреА , рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИ, рдФрд░ рдкреВрд░реЗ рдкрд░рд┐рдгрд╛рдо рд╡реИрд╕реЗ рднреА рд╕реНрдореГрддрд┐ рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗред рдиреАрдЪреЗ рдореИрдВ рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдореЗрдВ рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд▓рд╛рдКрдВрдЧрд╛ рдЬреЛ рд▓рдЧрднрдЧ Eratosthenes рдХреА рдЫрд▓рдиреА рдХреА рддрд░рд╣ рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреЛ рдореЗрдореЛрд░реА рд╕реЗ рдбрдмрд▓ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рджреЗрддрд╛ рд╣реИ (рдпрд╛рдиреА рдПрдХ рд╕реМ рдмрд┐рд▓рд┐рдпрди рддрдХ рдХреЗ рдкреНрд░рд╛рдЗрдо рдХрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд▓рдЧрднрдЧ 3 рдЧреАрдЧрд╛рдмрд╛рдЗрдЯ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓реЗрдЧрд╛, рдЬреЛ рдПрдХ рдорд╛рдирдХ рд▓реИрдкрдЯреЙрдк рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рдлрд┐рдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП)редрд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд░реЗрдЯреЛрд╕реНрдердиреАрдЬ рдХреА рдЫрд▓рдиреА рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ: 1 рд╕реЗ рдПрди рддрдХ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ, рджреЛ рд╕реЗ рд╡рд┐рднрд╛рдЬреНрдп рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдкрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рд╕рдВрдЦреНрдпрд╛ 3 рд╕реЗ рд╡рд┐рднрд╛рдЬреНрдп рд╣реЛрддреА рд╣реИ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рдмрд╛рдж рд╢реЗрд╖ рд╕рдВрдЦреНрдпрд╛ рд╕рд░рд▓ рд╣реЛрдЧреА:2 3 . 5 . 7 . 9 . 11 . 13 . 15 . 17 . 19 . 21 . 23 . 25 . 27 . 29 ...
2 3 . 5 . 7 . . . 11 . 13 . . . 17 . 19 . . . 23 . 25 . . . 29 ...
2 3 . 5 . 7 . . . 11 . 13 . . . 17 . 19 . . . 23 . . . . . 29 ...
рд╕реА # рдХреЛрдбclass EratospheneSieve
{
private bool[] Data;
public EratospheneSieve(int length)
{
Data = new bool[length];
for (int i = 2; i < Data.Length; i++) Data[i] = true;
for (int i = 2; i * i < Length; i++)
{
if (!Data[i]) continue;
for (int d = i * i; d < Length; d += i) Data[d] = false;
}
}
public int Length => Data.Length;
public bool IsPrime(int n) => Data[n];
}
рдореЗрд░реЗ рд▓реИрдкрдЯреЙрдк рдкрд░, рдпрд╣ 15 рдмрд┐рд▓рд┐рдпрди рд╕реЗрдХрдВрдб рддрдХ рдЧрд┐рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдореЗрдореЛрд░реА рдХреА рдПрдХ рдЧреАрдЧрд╛рдмрд╛рдЗрдЯ рдЦрдкрдд рдХрд░рддрд╛ рд╣реИредрд╣рдо рдЬрд┐рд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЙрд╕реЗ рд╡реНрд╣реАрд▓ рдлреИрдХреНрдЯрд░рд╛рдЗрдЬреЗрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдЗрд╕рдХреЗ рд╕рд╛рд░ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ 30 рдЯреБрдХрдбрд╝реЛрдВ рдХреА рдПрдХ рдЧреЛрд▓реА рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╕рдВрдЦреНрдпрд╛рдПрдБ рд▓рд┐рдЦрддреЗ рд╣реИрдВ: 0 1 2 3 4 5 ... 26 27 28 29
30 31 32 33 34 35 ... 56 57 58 59
60 61 62 63 64 65 ... 86 87 88 89
...
рдФрд░ 2, 3 рдФрд░ 5 рд╕реЗ рд╡рд┐рднрд╛рдЬреНрдп рд╕рднреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдкрд╛рд░ рдХрд░реЗрдВ:. 1 . . . . . 7 . . . 11 . 13 . . . 17 . 19 . . . 23 . . . . . 29
. 31 . . . . . 37 . . . 41 . 43 . . . 47 . 49 . . . 53 . . . . . 59
. 61 . . . . . 67 . . . 71 . 73 . . . 77 . 79 . . . 83 . . . . . 89
...
рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╕рдорд╛рди рдкрджреЛрдВ рдкрд░ рд╕рдВрдЦреНрдпрд╛рдПрдБ рдкрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдЪреВрдВрдХрд┐ рд╣рдордиреЗ рдХреЗрд╡рд▓ рдорд┐рд╢реНрд░рд┐рдд рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдкрд╛рд░ рдХрд┐рдпрд╛ (рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдВрдЦреНрдпрд╛ 2, 3, 5 рдХреЗ), рдлрд┐рд░ рдЕрднрд╛рдЬреНрдп рд╕рдВрдЦреНрдпрд╛рдПрдБ рдХреЗрд╡рд▓ рдЪрд┐рдиреНрд╣рд┐рдд рдкрджреЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВредрдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдЖрда рдРрд╕реА рд╕рдВрдЦреНрдпрд╛рдПрдБ рд╣реЛрддреА рд╣реИрдВ, рдпрд╣ рд╣рдореЗрдВ рдПрдХ рдмрд╛рдЗрдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рддреАрд╕ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдЖрда рдмрд┐рдЯреНрд╕ рд╕рдВрдЦреНрдпрд╛ рдХреА рд╕рд╛рджрдЧреА рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВрдЧреЗред рдпрд╣ рд╕рдВрдпреЛрдЧ рди рдХреЗрд╡рд▓ рд╕реМрдВрджрд░реНрдпрдкреНрд░рдж рд░реВрдк рд╕реЗ рд╕реБрдВрджрд░ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рднреА рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИ!
рддрдХрдиреАрдХреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдПрдХ рд╕реМ рдмрд┐рд▓рд┐рдпрди рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЪрд╛рд░ рдмрд╛рдЗрдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЕрдм рдирд╣реАрдВ рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░рд╛ рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:class Wheel235
{
private byte[] Data;
public Wheel235(long length)
{
...
}
public bool IsPrime(long n)
{
...
}
...
}
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЗ рд▓рд┐рдП, рд╣рдо 30 рддрдХ рд╡рд┐рднрд╛рдЬреНрдп рдирд┐рдХрдЯрддрдо рд╕рдВрдЦреНрдпрд╛ рддрдХ рдЧреЛрд▓ рдХрд░реЗрдВрдЧреЗред рддрдмclass Wheel235
{
private byte[] Data;
public Wheel235(long length)
{
length = (length + 29) / 30 * 30;
Data = new byte[length/30];
...
}
public long Length => Data.Length * 30L;
...
}
рдЕрдЧрд▓рд╛, рд╣рдореЗрдВ рджреЛ рд╕рд░рдгрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдПрдХ рд╕реВрдЪрдХрд╛рдВрдХ 0..29 рдХреЛ рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИ, рджреВрд╕рд░рд╛, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛ рддреАрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВред рдЗрди рд╕рд░рдгрд┐рдпреЛрдВ рдФрд░ рдмрд┐рдЯ рдЕрдВрдХрдЧрдгрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдбреЗрдЯрд╛ рд╕рд░рдгреА рдореЗрдВ рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдФрд░ рдмрд┐рдЯреНрд╕ рдХреЗ рдмреАрдЪ рдПрдХ-рд╕реЗ-рдПрдХ рдкрддреНрд░рд╛рдЪрд╛рд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреЗрд╡рд▓ рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: IsPrime (n), рдЬреЛ рдЖрдкрдХреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рдзрд╛рди рд╣реИ, рдФрд░ ClearPrime (n), рдЬреЛ рд╕рдВрдЧрдд рдмрд┐рдЯ рдХреЛ 0 рдкрд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рд╕рдВрдЦреНрдпрд╛ n рдХреЛ рдпреМрдЧрд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ:class Wheel235
{
private static int[] BIT_TO_INDEX = new int[] { 1, 7, 11, 13, 17, 19, 23, 29 };
private static int[] INDEX_TO_BIT = new int[] {
-1, 0,
-1, -1, -1, -1, -1, 1,
-1, -1, -1, 2,
-1, 3,
-1, -1, -1, 4,
-1, 5,
-1, -1, -1, 6,
-1, -1, -1, -1, -1, 7,
};
private byte[] Data;
...
public bool IsPrime(long n)
{
if (n <= 5) return n == 2 || n == 3 || n == 5;
int bit = INDEX_TO_BIT[n % 30];
if (bit < 0) return false;
return (Data[n / 30] & (1 << bit)) != 0;
}
private void ClearPrime(long n)
{
int bit = INDEX_TO_BIT[n % 30];
if (bit < 0) return;
Data[n / 30] &= (byte)~(1 << bit);
}
}
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рд╕рдВрдЦреНрдпрд╛ 2, 3 рдпрд╛ 5 рд╕реЗ рд╡рд┐рднрд╛рдЬреНрдп рд╣реИ, рддреЛ рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛ -1 рд╣реЛрдЧреА, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╕рдВрдЦреНрдпрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдордЧреНрд░ рд╣реИред рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдо рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ n = 5 рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВредрдЕрдм, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реА, рдЬреЛ рд▓рдЧрднрдЧ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ Eratosthenes рдХреА рдЪрд▓рдиреА рджреЛрд╣рд░рд╛рддрд╛ рд╣реИ: public Wheel235(long length)
{
length = (length + 29) / 30 * 30;
Data = new byte[length / 30];
for (long i = 0; i < Data.Length; i++) Data[i] = byte.MaxValue;
for (long i = 7; i * i < Length; i++)
{
if (!IsPrime(i)) continue;
for (long d = i * i; d < Length; d += i) ClearPrime(d);
}
}
рддрджрдиреБрд╕рд╛рд░, рдкреВрд░рд╛ рдкрд░рд┐рдгрд╛рдореА рд╡рд░реНрдЧ:рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИclass Wheel235
{
private static int[] BIT_TO_INDEX = new int[] { 1, 7, 11, 13, 17, 19, 23, 29 };
private static int[] INDEX_TO_BIT = new int[] {
-1, 0,
-1, -1, -1, -1, -1, 1,
-1, -1, -1, 2,
-1, 3,
-1, -1, -1, 4,
-1, 5,
-1, -1, -1, 6,
-1, -1, -1, -1, -1, 7,
};
private byte[] Data;
public Wheel235(long length)
{
length = (length + 29) / 30 * 30;
Data = new byte[length / 30];
for (long i = 0; i < Data.Length; i++) Data[i] = byte.MaxValue;
for (long i = 7; i * i < Length; i++)
{
if (!IsPrime(i)) continue;
for (long d = i * i; d < Length; d += i) ClearPrime(d);
}
}
public long Length => Data.Length * 30L;
public bool IsPrime(long n)
{
if (n >= Length) throw new ArgumentException("Number too big");
if (n <= 5) return n == 2 || n == 3 || n == 5;
int bit = INDEX_TO_BIT[n % 30];
if (bit < 0) return false;
return (Data[n / 30] & (1 << bit)) != 0;
}
private void ClearPrime(long n)
{
int bit = INDEX_TO_BIT[n % 30];
if (bit < 0) return;
Data[n / 30] &= (byte)~(1 << bit);
}
}
рдХреЗрд╡рд▓ рдПрдХ рдЫреЛрдЯреА рд╕реА рд╕рдорд╕реНрдпрд╛ рд╣реИ: рдпрд╣ рдХреЛрдб рд▓рдЧрднрдЧ 65 рдмрд┐рд▓рд┐рдпрди рд╕реЗ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ! рдЬрдм рдЖрдк рдЗрд╕реЗ рдРрд╕реА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:Unhandled Exception: System.OverflowException: Array dimensions exceeded supported range.
рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕реА # рд╕рд░рдгрд┐рдпреЛрдВ рдореЗрдВ 2 ^ 31 рд╕реЗ рдЕрдзрд┐рдХ рддрддреНрд╡ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдЬрд╛рд╣рд┐рд░ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЪрд╛рд░-рдмрд╛рдЗрдЯ рд╕рд░рдгреА рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)ред рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдмрд╛рдЗрдЯ [] рд╕рд░рдгреА рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд▓рдВрдмрд╛ [] рд╕рд░рдгреА, рд▓реЗрдХрд┐рди рдпрд╣ рдереЛрдбрд╝рд╛ рдЕрдВрдХрдЧрдгрд┐рдд рдХреЛ рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рдХрд░реЗрдЧрд╛ред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рд╣рдо рджреВрд╕рд░реЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рдЬрд╛рдПрдВрдЧреЗ, рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╡рд╛рдВрдЫрд┐рдд рд╕рд░рдгреА рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рддрд╛ рд╣реИ, рджреЛ рдЫреЛрдЯреА рд╕рд░рдгрд┐рдпреЛрдВ рдХреЛ рдЕрдВрджрд░ рд░рдЦрддрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рд╣рдо рдЙрд╕реЗ рдбрд┐рд╕реНрдХ рдкрд░ рдЦреБрдж рдХреЛ рдмрдЪрд╛рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗрдВрдЧреЗ рддрд╛рдХрд┐ рдЖрдк рдПрдХ рдмрд╛рд░ primes рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХреЗрдВ, рдФрд░ рдлрд┐рд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ: class LongArray
{
const long MAX_CHUNK_LENGTH = 2_000_000_000L;
private byte[] firstBuffer;
private byte[] secondBuffer;
public LongArray(long length)
{
firstBuffer = new byte[Math.Min(MAX_CHUNK_LENGTH, length)];
if (length > MAX_CHUNK_LENGTH) secondBuffer = new byte[length - MAX_CHUNK_LENGTH];
}
public LongArray(string file)
{
...
}
public long Length => firstBuffer.LongLength + (secondBuffer == null ? 0 : secondBuffer.LongLength);
public byte this[long index]
{
get => index < MAX_CHUNK_LENGTH ? firstBuffer[index] : secondBuffer[index - MAX_CHUNK_LENGTH];
set
{
if (index < MAX_CHUNK_LENGTH) firstBuffer[index] = value;
else secondBuffer[index - MAX_CHUNK_LENGTH] = value;
}
}
public void Save(string file)
{
...
}
}
рдЕрдВрдд рдореЗрдВ, рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░реЗрдВрдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдгclass Wheel235
{
class LongArray
{
const long MAX_CHUNK_LENGTH = 2_000_000_000L;
private byte[] firstBuffer;
private byte[] secondBuffer;
public LongArray(long length)
{
firstBuffer = new byte[Math.Min(MAX_CHUNK_LENGTH, length)];
if (length > MAX_CHUNK_LENGTH) secondBuffer = new byte[length - MAX_CHUNK_LENGTH];
}
public LongArray(string file)
{
using(FileStream stream = File.OpenRead(file))
{
long length = stream.Length;
firstBuffer = new byte[Math.Min(MAX_CHUNK_LENGTH, length)];
if (length > MAX_CHUNK_LENGTH) secondBuffer = new byte[length - MAX_CHUNK_LENGTH];
stream.Read(firstBuffer, 0, firstBuffer.Length);
if(secondBuffer != null) stream.Read(secondBuffer, 0, secondBuffer.Length);
}
}
public long Length => firstBuffer.LongLength + (secondBuffer == null ? 0 : secondBuffer.LongLength);
public byte this[long index]
{
get => index < MAX_CHUNK_LENGTH ? firstBuffer[index] : secondBuffer[index - MAX_CHUNK_LENGTH];
set
{
if (index < MAX_CHUNK_LENGTH) firstBuffer[index] = value;
else secondBuffer[index - MAX_CHUNK_LENGTH] = value;
}
}
public void Save(string file)
{
using(FileStream stream = File.OpenWrite(file))
{
stream.Write(firstBuffer, 0, firstBuffer.Length);
if (secondBuffer != null) stream.Write(secondBuffer, 0, secondBuffer.Length);
}
}
}
private static int[] BIT_TO_INDEX = new int[] { 1, 7, 11, 13, 17, 19, 23, 29 };
private static int[] INDEX_TO_BIT = new int[] {
-1, 0,
-1, -1, -1, -1, -1, 1,
-1, -1, -1, 2,
-1, 3,
-1, -1, -1, 4,
-1, 5,
-1, -1, -1, 6,
-1, -1, -1, -1, -1, 7,
};
private LongArray Data;
public Wheel235(long length)
{
length = (length + 29) / 30 * 30;
Data = new LongArray(length / 30);
for (long i = 0; i < Data.Length; i++) Data[i] = byte.MaxValue;
for (long i = 7; i * i < Length; i++)
{
if (!IsPrime(i)) continue;
for (long d = i * i; d < Length; d += i) ClearPrime(d);
}
}
public Wheel235(string file)
{
Data = new LongArray(file);
}
public void Save(string file) => Data.Save(file);
public long Length => Data.Length * 30L;
public bool IsPrime(long n)
{
if (n >= Length) throw new ArgumentException("Number too big");
if (n <= 5) return n == 2 || n == 3 || n == 5;
int bit = INDEX_TO_BIT[n % 30];
if (bit < 0) return false;
return (Data[n / 30] & (1 << bit)) != 0;
}
private void ClearPrime(long n)
{
int bit = INDEX_TO_BIT[n % 30];
if (bit < 0) return;
Data[n / 30] &= (byte)~(1 << bit);
}
}
рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рдорд┐рд▓рд╛, рдЬреЛ рдПрдХ рд╕реМ рдЕрд░рдм рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрд░рд╛рдзреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдбрд┐рд╕реНрдХ рдкрд░ рд╕рд╣реЗрдЬ рд╕рдХрддрд╛ рд╣реИ (рдореЗрд░реЗ рдкрд╛рд╕ 50 рдорд┐рдирдЯ рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рд▓реИрдкрдЯреЙрдк рдкрд░ рдпрд╣ рдХреЛрдб рдерд╛; рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЖрдХрд╛рд░ рд▓рдЧрднрдЧ 3 рдЧреАрдЧрд╛рдмрд╛рдЗрдЯ рдерд╛, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛): long N = 100_000_000_000L;
Wheel235 wheel = new Wheel235(N);
wheel.Save("./primes.dat");
рдФрд░ рдлрд┐рд░ рдбрд┐рд╕реНрдХ рд╕реЗ рдкрдврд╝реЗрдВ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ: DateTime start = DateTime.UtcNow;
Wheel235 loaded = new Wheel235("./primes.dat");
DateTime end = DateTime.UtcNow;
Console.WriteLine($"Database of prime numbers up to {loaded.Length:N0} loaded from file to memory in {end - start}");
long number = 98_000_000_093L;
Console.WriteLine($"{number:N0} is {(loaded.IsPrime(number) ? "prime" : "not prime")}!");