On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 01.11.18 20:01. Заголовок: C-функция, определяющая, является ли целое число простым.


Эта тема создана на основе вопроса на Stackoverflow C program to take integer if it is Prime or Not Prime и связана с тем, как написать C-функцию, определяющую, является ли целочисленное число простым.

Глядя, как реализована такая функция в ответах к указанному вопросу, создается впечатление, что даже написание такой функции вызывает у многих программистов трудности.

Вот пара примеров реализации этой функции, присутствующей в ответах.

 
int isprime(long n) {
for (long i = 2; i != n; ++i)
if (n%i == 0)
return 0;
return 1;
}

 
int isprime(long n) {
if(n > 1 && n <= 3)
return 1;
if(abs(n) == 1)
return 0;
if(n%2 == 0)
return 0;

for (long i = 3; i <= sqrt(n); i += 2)
if (n%i == 0)
return 0;
return 1;
}

Первая реализация этой функции вообще некорректна, так как для чисел 0 и 1, которые не являются простыми, цикл имеет неопределенное поведение. Аналогично поведение цикла для отрицательных аргументов функции.

И вторая реализация функции неверная. Во-первых, для чисел типа long int следует вызывать функцию labs вместо функции abs. Во-вторых, отрицательные числа за исключением числа -1 также попадают в категорию простых чисел. К тому же функция слишком усложнена и имеет аж 5(!) предложений return.

И в любом случае возникает вопрос: а что делать, если нужно определить, является ли число, например, типа unsigned long int или long long int или unsigned long long int простым? Писать для каждого из этих типов отдельную функцию, выдумывая для нее новое имя, так как в C отсутствует перегрузка функций?

Так, как правильно написать реализацию функции, определяющую, является ли целое число простым?

Во-первых, отметим, что понятие простого числа вводится для чисел натурального ряда. Поэтому параметр функции следует сделать беззнаковым целым типом. Во-вторых, следует выбрать максимальный беззнаковый целый тип такой, как, например, unsigned long long int. Тогда такую функцию можно вызывать для аргумента любого беззнакового целочисленного типа.

Теперь рассмотрим вопрос: какой тип следует назначить для возвращаемого значения функции. Можно было бы использовать тип _Bool. Но тогда такую функцию нельзя будет использовать в проекте на базе языка C++, так как в C++ такой целочисленный тип отсутствует. Поэтому тип возвращаемого значения лучше задать тип int.

Ниже приведена демонстрационная программа, показывающая реализацию и использование функции, определяющей, является ли целое число простым.
 
#include <stdio.h>

int isprime( unsigned long long int x )
{
int prime = x % 2 == 0 ? x == 2 : x != 1;

for ( unsigned long long int i = 3; prime && i <= x / i; i += 2 )
{
prime = x % i != 0;
}

return prime;
}

int main( void )
{
const int N = 100;

for ( int i = 0; i < N; i++ )
{
if ( isprime( i ) ) printf( "%d ", i );;
}
putchar( '\n' );
}

Вывод программы на консоль:
 
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


Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 2
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет