#c #expression #primes #integer-arithmetic #function-definition
#c #выражение #простые числа #целое число-арифметика #функция-определение
Вопрос:
Я написал программу на c, чтобы проверить, является ли число простым с возможностью усечения слева или нет. Но это не работает. num_digit используется для подсчета цифр, prime_check — для проверки, является ли число простым или нет. Я не очень разбираюсь в C, я новичок.
#include<stdio.h>
#include<math.h>
// to check left truncated prime numbers
int main()
{
int num,flag=0;
printf("enter a numbern");
scanf("%d", amp;num);
while (num>0)
{
if (prime_check(num)==1) // 1 = true
{
int y=num_digit(num);
num = num-((num/pow(10,(y-1)))*pow(10,(y-1)));
}
else
{
flag=1;
break;
}
}
if (flag==0) printf("Congrats, its a left truncated prime number");
else printf("nope no nevern");
}
int prime_check(int n)
{
int i,flag=0;
if (n<=1) return 0;
else if (n<=3) return 1;
else
{
for (i=2;i<=sqrt(n);i )
{
if(n%i==0)
{
flag=1;
break;
}
}
}
if(flag==0) return 1;
else return 0;
}
int num_digit(int n)
{
int i,x=0;
for (i=1;n!=0;i )
{
n=n/10;
x ;
}
return x;
}
Кто-нибудь может подсказать мне, какой шаг неверен? все, что он делает, это проверяет, является ли число простым или нет.
Комментарии:
1.
pow(10, 3)
может возвращать что-то вроде999.99999999675321
. Может быть, округлите его или, лучше (??), напишите свою собственную целочисленную степенную функцию2. @Aman Kumar Где объявлена переменная x, используемая в операторе x= 1;?
3.
for (i=2;i<=sqrt(n);i )
могут возникнуть проблемы с усечением FP.; Предложитьfor (i=3;i<=n/i;i =2)
4. @VladfromMoscow мой плохой, это не x, это на самом деле «флаг». кстати, это все еще не работает.
5. @pmg можете ли вы предложить способ записи степенной функции
Ответ №1:
Вы не должны использовать выражения с плавающей запятой. Они могут привести к неожиданному результату.
Например, давайте предположим, что num
это равно 13
.
В этом случае выражение
num/pow(10,(y-1))
выдаст значение double 1.3
, поскольку возвращаемый тип функции pow
double . Таким образом, все выражение также будет иметь тип double . Код не использует целочисленную арифметику.
Теперь выражение
((num/pow(10,(y-1)))*pow(10,(y-1)))
даст двойное значение, равное 13
(1.3 * 10 == 13)
В результате переменная num
после этого оператора
num = num-((num/pow(10,(y-1)))*pow(10,(y-1)));
будет равно 0
вместо ожидаемого значения 3
.
Без использования функций с плавающей запятой программа, например, может выглядеть следующим образом.
#include <stdio.h>
int is_prime( unsigned long long n )
{
int prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned long long i = 3; prime amp;amp; i <= n / i; i = 2 )
{
prime = n % i != 0;
}
return prime;
}
size_t number_size( unsigned long long int n )
{
const unsigned long long Base = 10;
size_t size = 0;
do
{
size;
} while ( n /= Base );
return size;
}
int main( void )
{
const unsigned int Base = 10;
unsigned n = 0;
printf( "Enter a non-negative number: " );
scanf( "%u", amp;n );
size_t size = number_size( n );
unsigned int power = 1;
while ( --size ) power *= Base;
for ( unsigned int tmp = n; power amp;amp; is_prime( tmp ); power /= Base )
{
tmp %= power;
}
if ( power == 0 )
{
printf( "Congrats, %u is a left truncated prime number.n", n );
}
else
{
printf( "nope no never.n" );
}
return 0;
}
Например, числа 17
13
являются простыми числами с возможностью усечения слева, в то время как числа 19
11
не являются простыми числами с возможностью усечения слева.