How to determine which condition was true? - c

Say I have a few conditions inside a if statement:
if(x < 0 || x > 10 || x == 5)
{
}
If either x is greater than 10 or less than 0 or equal to 5, I want the program to stop working.
if(x < 0 || x > 10 || x == 5)
{
stop(); // PSEUDO CODE
}
However, I want the program to say something depending on which condition was true. Something like this:
if(x < 0 || x > 10 || x == 5)
{
if(x < 0)
{
printf("your number was less than 0");
}
if(x > 10)
{
printf("your number was greater than 10");
}
if(x == 5)
{
printf("wow, your number is equal to 5!");
}
stop(); // PSEUDO CODE
}
That's a horrible way of doing it because it unnecessarily checks for the conditions twice; how can I do the same in a more efficient way?

Why make things complicated? Just remove the outer check, and put stop() inside both of the inner ones:
if(x < 0)
{
printf("your number was less than 0");
stop();
}
if(x > 10)
{
printf("your number was greater than 10");
stop();
}
You can even use an else if if you want.

Save the boolean result in a variable and reuse it inside. Redundancy is ok sometimes. Just check/count the number of executions if it's possible to be lessen down.
bool isXNegative = x < 0;
bool isXMoreThan = x > 10;
bool isXFive = (x == 5);
//for specific conditions
if(isXNegative)
{
printf("your number was less than 0");
}
if(isXMoreThan)
{
printf("your number was greater than 10");
}
if(isXFive)
{
printf("wow, your number is equal to 5!");
}
//for combination of the conditions.
if(isXNegative || isXMoreThan || isXFive)
{
//common code here for all the conditions.
stop(); // PSEUDO CODE
}
//else if(another condition combination here...){...}
//else {...}

You can set a flag in the failure cases, then check the flag afterward to do the cleanup.
int do_stop = 0;
if(x < 0)
{
printf("your number was less than 0");
do_stop = 1;
}
if(x > 10)
{
printf("your number was greater than 10");
do_stop = 1;
}
if(x == 5)
{
printf("wow, your number is equal to 5!");
do_stop = 1;
}
if (do_stop) {
stop();
}

Assuming you do want to be complicated, save some keystrokes and take advantage of short-circuiting, you can assign expression results to variables in the if condition like so:
int c1, c2, c3;
if ((c1 = x < 0) || (c2 = x > 10) || (c3 = x == 5)) {
if (c1) {
printf("your number was less than 0\n");
} else if (c2) {
printf("your number was greater than 10\n");
} else {
printf("wow, your number is equal to 5!\n");
}
}
Just be aware that if the condition short-circuits (say x < 0), then the value of c2 and c3 is not initialized.
I don't actually advocate writing your code this way, but this language feature can be useful and I didn't see it mentioned.

Related

Certain values give incorrect results for prime number checking function

I recently wrote a program in C for a calculator. To produce a function that checks if the user input is a prime number or not (amongst other functions).
I essentially used this code (excluding all other functions):
#include <stdio.h>
#include <math.h>
int testForPrime(int);
int main(void) {
int ioperand1 = 0;
printf("\nEnter the value to check if prime (positive integer): ");
scanf("%d", &ioperand1);
if (testForPrime(ioperand1) != 0)
printf("\nThis number is prime.\n");
else
printf("\nThis number is not prime.\n");
return 0;
}
int testForPrime(int operand1) {
int i = 0;
for (i = 2; i <= sqrt(operand1); i++) {
if (operand1 == 0 || operand1 == 1)
return 0;
else if (operand1 % i == 0)
return 0;
else
return 1;
}
}
^
This code above produces the errors
I am not sure why the code produces an error for the value 9 (I fixed that above by adding the condition: if (operand1 == 9), but I don't understand why 9 is seemingly the only value that results in an incorrect solution (It would say 9 was prime, but not any other number give an incorrect result).
One other bug that I remidied with an extra condition statement was the value of 2.
Before adding the extra conditional statement in the main function: if (ioperand1 == 2), the value 2 would always come up as a non prime number.
I originally found this solution to check for prime numbers online, and I still don't understand why the for loop starts from 2.
#include <stdio.h>
#include <math.h>
int testForPrime(int);
int main(void) {
int ioperand1 = 0;
printf("\nEnter the value to check if prime (positive integer): ");
scanf("%d", &ioperand1);
if (testForPrime(ioperand1) != 0 || ioperand1 == 2)
printf("\nThis number is prime.\n");
else
printf("\nThis number is not prime.\n");
return 0;
}
int testForPrime(int operand1) {
int i = 0;
for (i = 2; i <= sqrt(operand1); i++) {
if (operand1 == 0 || operand1 == 1 || operand1 == 9)
return 0;
else if (operand1 % i == 0)
return 0;
else
return 1;
}
}
^This code above fixed the problem, though I don't undesttand why the problem existed in the first place.
TL;DR:
I don't know why this code doesn't work without the extra conditional statements:
if (operand1 == 9) in function definition,
and
if (ioperand1 == 2) in main function.
If anyone could help clear this up, I'd appreciate it.
It is because your prime checking loop does not iterate. It always returns on the first iteration. It must run to completion, and then the number will be prime. So
int testForPrime(int operand1) {
if(operand1 < 2) {
return 0;
}
int sr = (int)round(sqrt(operand1));
for(int i = 2; i <= sr; i++) {
if (operand1 % i == 0) {
return 0;
}
}
return 1;
}

Boolean Logic in AND statement

I created a program that calculates the divisibility by 3 and 5. If divisible by 3 print 'CS' and if divisible by 5 print 'CS1714'. If divisible by both print 'CS1714'. If not divisible by 3 or 5 print 'ERROR'.
My code executes properly. However is it possible for the Boolean && to break if say both values are false. Also why does the code print 'CSERROR' when input is 98988?
#include <stdio.h>
int main(void)
{
int userInput;
scanf("%d", &userInput);
if((userInput % 3) == 0){
printf("CS");
}
if((userInput % 5) == 0){
printf("1714");
}
else if(!((userInput % 5) == 0 && (userInput % 3) == 0)){
printf("ERROR");
}
return 0;
}
When the input is 98988 it is printing CSERROR because the number 98988 is divisible by 3 and that is why the first if condition is true and thus it prints CS, and then you gave another if where you are checking if the number is divisible by 5 or not, if the number is divisible by 5 then you print 1714, else you print ERROR, as 98988 is not divisible by 5 that is why it goes to the else part and prints ERROR (The last else will always true if your second if is false. So, here is a logical error). Previously it printed CS and now it printed ERROR, combinedly you are seeing CSERROR.
One is need to be clear that, the if-else blocks structures are like below, and it started implementing from a if to go further until finds a true condition or else.
if(condition){
}
else if(condition){
}
else{
}
You should check both conditions (when the number is divisible by 3 and also divisible by 5) first, then check whether it is divisible by 3 , if not then check by 5. And finally if all are false that means it is not divisible by 3 and also not divisible by 5, so print error.
The code should be like:
#include <stdio.h>
int main(void)
{
int userInput;
scanf("%d", &userInput);
if(((userInput % 5) == 0 && (userInput % 3) == 0)){
printf("CS1714");
}
else if((userInput % 3) == 0){
printf("CS");
}
else if((userInput % 5) == 0){
printf("1714");
}
else{
printf("ERROR");
}
return 0;
}
Input: 98988
Output: CS
#include <stdio.h>
int main(void)
{
int userInput;
scanf("%d", &userInput);
if((userInput % 3) == 0){
printf("CS");
}
if((userInput % 5) == 0){
printf("1714");
}
else if(((userInput % 5) != 0 && (userInput % 3) != 0)){
printf("ERROR");
}
return 0;
}

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.

How to know if a number is positive or negative or 0 [duplicate]

This question already has answers here:
Checking whether a number is positive or negative using bitwise operators
(18 answers)
How do I find whether a number is positive, negative or zero without using if or for? [duplicate]
(3 answers)
Closed 9 years ago.
Is it possible to know if a number is positive or negative or 0 in c language using only two if conditions?
If yes, then how? please let me know
Use only two ifs:
if (num <= 0) {
if (num == 0) {
/* num is zero */
} else {
/* num is negative */
}
} else {
/* num is positive */
}
I hope this can solve your problem
#include <stdio.h>
int main()
{
float num;
printf("Enter a number: ");
scanf("%f",&num); // Take input from user
if (num<=0) // if Number is >= 0
{
if (num==0) // if number is equal to zero
printf("You entered zero.");
else // if number is > 0
printf("%.2f is negative.",num);
}
else // if number is < 0
printf("%.2f is positive.",num);
return 0;
}
If c is a floating point, the problem becomes interesting.
c may be
1) > 0
2) < 0
3) = 0
4) "Not-a-Number"
#include <math.h>
...
int classification = fpclassify(x);
if (classification == FP_NAN || classification == FP_ZERO)) {
if (classification == FP_NAN) puts("NaN")
else puts("zero");
}
else {
if (signbit(x)) puts("< 0" )
else puts("> 0");
}
At most, 2 if()s executed.
Without using classification functions/macros
if (x != x || x == 0.0)) {
if (x != x) puts("NaN")
else puts("zero");
}
else {
if (x < 0.0) puts("< 0" )
else puts("> 0");
}

Resources