C programming - Checking prime number - c

I am trying to check whether a given number is prime but I've run into an issue. This is the code:
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
bool isPrime(int input)
{
for (int i = sqrt(input); i >= 2; i--)
{
if (input % i == 0)
{
return false;
}
return true;
}
}
int main()
{
int input;
scanf("%d", &input);
if (isPrime(input))
{
printf("Is prime number");
} else
{
printf("Is not prime number");
}
return 0;
}
In the code block of my isPrime function, if I put return true; in the for loop like above, this will be wrong in some cases (for example, when input is 10, it will declare that 10 is a prime number). But if I put return true; outside the for loop, it works fine. So what is the difference?

Let's walk through your loop:
for (int i = sqrt(input); i >= 2; i--)
{
If the input is 10, then i starts out as 3 (remember that when assigning a floating-point value to an int, the fractional portion is discarded). 3 is greater than or equal to 2, so the loop body executes.
if (input % i == 0)
{
The remainder of 10 divided by 3 is not zero, so we do not enter the body of the if statement.
return false;
}
return true;
}
And then we immediately return true.
Because of this, no matter what input you provide, your loop will only iterate 1 time. If input is evenly divisible by the integer value of its square root (such as 9, 16, or 25), then the body of the if statement is executed and it returns false, otherwise it unconditionally returns true.
For your function to work properly, you must move the return true; statement outside the body of the loop - you should only return true when you've exhausted all values of i between sqrt(input) and 2.

The function returns true if the first divisor in the for loop does not divide the target number.
because this return statement
return true;
is inside the for loop.
bool isPrime(int input)
{
for (int i = sqrt(input); i >= 2; i--)
{
if (input % i == 0)
{
return false;
}
return true;
}
}
Moreover the function has undefined behavior if it is called for example for prime numbers 2 or 3 or if a non-positive number is passed to the function.
Placing the return statement
return true;
outside the loop does not make your function correct.
Pay attention to that there is no sense to check even numbers except the number 2 whether they are prime or not prime.
The function can be written the following way
bool isPrime( unsigned long long n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned long long int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
The function can be called like
unsigned int input;
scanf("%u", &input);
if (isPrime(input))
{
printf("Is prime number");
} else
{
printf("Is not prime number");
}

When you put return true; inside of the loop, that statement will be executed whenever the preceding if condition is false. You only want to return true once you've completed your for loop and have found no divisors. That's why the return statement needs to be outside the loop.

This happens because your for loop isn't over with the complete traverse of i, but the return true statement tells the code to execute it the very first time your if condition goes false, and then exit the loop. So, imagine I give you 10 chocolate bars and tell you to take a bite from each, and only collect the dark ones. You take a bite on the first, it's sweet, you put it away. You take a bite on the second and it's dark. You collect it and you tell me you are done, although you actually aren't (You didn't check the rest of the chocolate bars to see if there are more dark ones there or not). That's what you are doing in your code. Hope the example is clear and helpful :)

Related

C programming function calling to return values

I'm a college student in my first year of software engineering. I am in the fourth week of my semester and am having trouble in my programming class. Currently, I was given this assignment in which I was given a function called "getNum()" and I had to use it in another function where the program user, would input a number and the function that I program (must be named isOdd()) would determine if the number is odd or even. Then the main function would print whether the number is odd or even. This is the way that my professor worded it:
" Write a program that uses the getNum() function provided to you in Assignment 2 to get anumber from the user (prompting them first, as always). Create and use a function called isOddwith parameters (the number) and return values (1 ifthe number is odd, 0 if the number is evenOR use a bool or boolean data type, your choice) to determine if thenumber is odd. In main(), tell the user (by displaying using printf()or cout) whether the number is evenor odd."
Now, the problem I am having is understanding programming as I am fairly new to it and some words confuse me, such as parameter and return value. To give you and idea of what I have written so far,
#include <stdio.h>
int isOdd(int numInput);
int getNum(void);
int main(void)
{
int number = 0;
while (number > -1)
{
if (isOdd(0))
{
printf("The number is even.\n");
}
else if (isOdd(1))
{
printf("The number is odd.\n");
}
}
return 0;
}
int isOdd(int numInput)
{
int myNumber = 0;
printf("Please enter a number: ", numInput);
myNumber = getNum();
if (myNumber % 2 == 0)
{
myNumber == 0;
}
else
{
myNumber == 1;
}
return myNumber;
}
#pragma warning(disable: 4996)
int getNum(void)
{
/* the array is 121 bytes in size; we'll see in a later lecture how we can improve this code */
char record[121] = { 0 }; /* record stores the string */
int number = 0;
/* NOTE to student: indent and brace this function consistent with your others */
/* use fgets() to get a string from the keyboard */
fgets(record, 121, stdin);
/* extract the number from the string; sscanf() returns a number
* corresponding with the number of items it found in the string */
if (sscanf(record, "%d", &number) != 1)
{
/* if the user did not enter a number recognizable by
* the system, set number to -1 */
number = -1;
}
return number;
}
This is what I have written, trying to do things accordingly to my professor's instructions, as I do not yet know how to properly use booleans. As you can see, at the bottom is the getNum() function that my professor has said is mandatory for this assignment. As of now, everything I input, I am told is even. I am not asking for you guys to solve and do everything for me but I want to understand what I am doing wrong, what my thinking is doing wrong and to overall better my understanding for future programming. Thank you
It's hard to help you without knowing why you did what you did. A lot of the code is just baffling:
if (isOdd(0))
Why are you passing a zero to isOdd?
printf("Please enter a number: ", numInput);
myNumber = getNum();
Is numInput supposed to be the number they enter or is myNumber supposed to be?
if (myNumber % 2 == 0)
{
myNumber == 0;
}
The statement myNumber == 0 compares myNumber to zero to see if they're equal. It does nothing useful here since you ignore the result of the comparison.
The function:
int getNum(void)
Takes no parameters (void), and returns an integer (int) value. The function itself accepts input from the standard input (stdin) stream - this is normally from the keyboard.
To complete your assignment you should write a function:
int isOdd( int value ) ;
Where value is an integer parameter and the return value is 1 if value is odd and 0 if it is even. Alternatively you are allowed to use the Boolean type:
#include "bool.h"
bool isOdd( int value ) ;
In which case you would return true for odd, and false for even.
Your isOdd() includes the getNumber() call and user prompt code. Not only is that not specified in the assignment, it is poor design making isOdd() difficult to use in more general situations. The assignment explicitly requires you to pass the value to be tested as a parameter.
The assignment does not require you to iterate the test (the while loop is not needed). The user input prompt and acceptance should be in main as follows:
int main(void)
{
printf( "Please enter a number: " ) ;
fflush( stdin ) ; // you'll may this on some platforms
int myNumber = getNum();
if( isOdd( myNumber ) )
{
printf("The number is odd.\n");
}
else
{
printf("The number is even.\n");
}
}
return 0;
}
Note that there are only two possible outcomes, so you do not need an else if( !isOdd( myNumber ) ... - if it is not odd it is implicitly even.
Your isOdd() function will work, but is over complicated. You are required to return a Boolean (a type with two possible values true/false - or an integer 1/0 which can be implicitly converted to a Boolean), and (myNumber % 2 == 0) is a Boolean expression (an expression with two possible results true or false). Anywhere you see the pattern:
if( <boolean expression> )
{
b = true ;
}
else
{
b = false ;
}
you can simply write:
b = <boolean expression> ;
In your case the Boolean determination of odd-ness is simply value % 2 != 0. You can return that directly:
bool isOdd( int value )
{
return value % 2 != 0 ;
}

C - Recursive function smaller prime numbers

i got this exercise where it wants me to create a function to check if a number is "Prime", and than create another function to print how many smaller prime numbers are there from the one i checked. The thing is i need to create a recursive function to check the number of smaller prime numbers using the first function(the one that checks if a number is prime or not). This is what i got so far, and i'm stuck here. The recursive function is confusing for me.
#include <stdio.h>
int main() {
int a;
scanf("%d", &a);
checkPrime(a);
smallerPrime(a);
}
int checkPrime (int number) {
if(number % 2 == 0) {
return 1;
} else {
return 0;
}
}
int smallerPrime (int number) {
if(checkPrime(number) % 2 != 0){
return ;
} else {
return ;
}
}
I saw from the comments,that you actually want to check if a number is even,and if so,you want to know how many smaller even numbers there are using recursion,not prime numbers as mentioned in the title,so my answer will refer that.
You could use something like this:
int smallerPrime (int number) {
static int count = -1; // so that the number itself will not be counted
if(number <1) //excluding 0 or negative numbers
return 0;
if(number !=2) {//we know the number has to be even so no check is needed
++count;
smallerPrime(number - 2);
return count+1; // the +1 is in order to count 2 as well
}
else {
return 0;
}
So for example:
Input 10 would give output 4 (8,6,4,2)
As mentioned by paxdiablo,using recursion here is not the best idea.
In case of very big numbers,your program will probably crash.
Furthermore,note that this code works for positive numbers only,as i am not sure if you want to count anything but them(Negative numbers (like -2,-4 and so on) and 0 are also considered even).
I excluded them here.
In main,you need to put the return value of checkPrime in some variable,and use it to determine if you need to use smallerPrime function.
So you should correct that in your code.
Of course,you can do it all in one function with some small changes.

Exit do loop when condition isn't met / Output answer incorrect

2 questions. 1 - I'm struggling to figure out how to exit this loop when a negative number is entered. 2 - my section of code regarding checking if the sum of the digits of a number isn't working correctly and need a different equation to get the correct output but cant figure it out. That part of the code needs to add the digits of an integer and output whether the sum is odd or even.
int main(void)
{
int number, sum, i;
int divisor, prime;
do {
printf("Enter an integer:");
scanf("%d", &number);
i = number;
sum = 0;
if (i % 7 == 0) {
printf("Multiple of 7\n");
} else if (i % 11 == 0) {
printf("Multiple of 11\n");
} else if (i % 13 == 0) {
printf("Multiple of 13\n");
}
if (i % 2 == 0) {
printf("Is sum of digits Odd? 1\n");
} else {
printf("Is sum of digits Odd? 0\n");
}
int check = 1;
for (divisor = 2; divisor <= i / 2; ++divisor) {
if (i % divisor == 0) {
check = 0;
break;
}
}
if (check == 0) printf("Is number prime? 0\n");
else printf("Is number prime? 1\n");
} while (i > 0);
return (0);
}
This should work:
...
do {
printf("Enter an integer:");
scanf("%d", &number);
if ( number < 0 )
break ;
...
One way to exit a loop with certain condition in C is using BREAK
if( a < 0) {
/* terminate the loop using break statement */
break;
}
When a negative number is entered, you can check with an if condition just after taking the input, and use exit(0).
Like
if(number < 0)
exit(0);
What you are doing will not work. Because you've used the while condition at the end, the modulus functions may not work(I'm not so sure, but I think the modulus function needs a positive integer as an argument)
You're not checking the sum of digits of the number in your code, but only if the number itself is even or odd.
The part would be
while(i > 0)
{
sum += i % 10;
i /= 10;
}
That should give you the sum of the digits, and you can check if it is odd or even
Anyway, the prime part will completely fail when a negative number, or even 1 is entered.
If you mean that you don't want to enter the loop at all, you can use a while loop instead of a do while loop.
You would have to get the first input before entering the loop, though, and would need another input at the bottom of the loop. This probably isn't what you want.
You probably want to use
if (number < 0) break;
And that would go right after you read the value.
If you do this, you don't need
while (i > 0);
At the end of your loop, you can just use
while (true);
Personally, I use while loops in such cases but that's really just a stylistic choice.
In any case, there is no need to check the value twice.

How can I compute if a value is prime or not faster?

My programs runs well in my compiler but it shows time limit exceeds in online contest compiler.
First line of input will contain a number N = number of test cases. Next N lines will contain number n as test case where 0<=n<=1000000000
Here is my code.
#include<stdio.h>
void main()
{
long t,n,i;
int f = 0;
scanf("%lu",&t);
while(t--)
{
scanf("%lu",&n);
f=0;
if(n==0 || n==1)
{
printf("NOT PRIME\n");
}
else
{
for(i=2;i<=n/2;i++)
{
if(n%i == 0)
{
printf("NOT PRIME\n");
f =1;
break;
}
}
if(f==0)
{
printf("PRIME\n");
}
}
}
}
How can I execute this program faster. Help me. Thanks in advance.
You can iterate to square root of n instead of n/2. Also you can pre-calculate all the prime factors in the range of square root of 1000000000 before the while loop. Then try to divide n with the prime factors that are less than or equal to sqrt(n) to check if it is prime or not.
The for loop:
(i = 3; i <= sqrt(n); i += 2) // skip 2 because it's the only even prime
Also you only need to test odd numbers for primality (two being the only even prime).
And compile with optimization, e.g. -O3 if using gcc.
You can make with increment 2:
My function to verify if a number is prime:
bool check(int n)
{
int i, j;
bool isprime;
if(n%2 == 0 || n == 0 || n == 1)
{
isprime = false;
}
else if(n == 2 || n == 3)
{
isprime = true;
}
else
{
for(i = 3; i<n; i+=2)
{
if(n%i == 0)
{
isprime = false;
break;
}
else if(i == n-2)
{
isprime = true;
break;
}
}
}
return isprime;
}
Remembering that call a function is less fast than use directly in main function.
Without changing your algorithm:
for(i=2;i<=n/2;i++)
might be faster as:
for(i=2, m=n/2; i<=m; ++i)
you only calculate the end value once, and preincrement doesn' compute an intermediate value like the post increment does.
However, with decent compiler optimizations, both of these will already be done.
Without looking at the generate assembly, it is hard to do any aggressive optimization.

C-Code...trying to combine a while loop with an OR operator to check if the input number is prime or not

Hey guys so this is the ques which i have coded but its not working properly..i cant seem to understand where am i going wrong..
Write a program that determines if a number that the user has entered is a prime
number. The program will continue to ask for numbers until the user enters a
value less than 2.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
int num;
int count = 1;
bool check = true;
do{
printf("Enter a number: ");
scanf("%d", &num);
count = num - 1;
bool check = false;
while (count > 1 || num % count == 0){
check = true;
count--;
}
if (check == true){
printf("%d is a prime number\n", num);
}
else
printf("%d is not a prime number\n", num);
}
while (num > 2);
}
while (count > 1 || num % count == 0){
check = true; // <-
count--;
}
On the indicated line you set check to true - this means that if the body of the loop executes even once, check will be true after the loop and the program will indicate that the number is prime. What you should do instead is show the number as prime iff the entire loop runs to completion.
The loop condition is also wrong; num % count == 0 indicates that the number is not prime, so you can stop checking if that is true. (Hint: you can terminate the loop from within using break)
Also if the user enters 2 or less, the checks will still run before the outer loop terminates.
You'll want your while loop to look like this:
bool prime = true;
while (count > 1 && prime) {
prime = ((num % count) != 0);
count--;
}
The way you wrote it will assign check to true on the first iteration, regardless of num's primality.
Say
int num = 3;
or whatever number you want bigger than 2
instead of
int num;
This is to make use you enter the loop.

Resources