Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

&& operator behaves like || operator

Tags:

c#

.net

logic

I am a beginner and I've been trying to run a program that prints all the numbers from 1 to N (user input) except for those that are divisible by 3 and 7 at the same time. What my code does instead, however, is that it prints the numbers from 1 to N except for those that are divisible by 3 or 7. I examined it for a while and I have no idea why it does that. Please explain to me where I'm going wrong.

static void Main(string[] args)
{
    int n = 0;
    int a = 0;
    n = Convert.ToInt32(Console.ReadLine());
    while (a <= n)
    {
        a++;
        if (a % 3 != 0 && a % 7 != 0)
        {
            Console.WriteLine(a);
        }
    }
    Console.ReadKey();
}

When I reverse the signs of the if statement to == the && operator works properly, but if the sign is != it simply acts like an || operator, so that confuses me even more. The issue is most likely in the condition, but I can't see what is wrong with it.

like image 485
Ornstein Avatar asked Sep 10 '15 10:09

Ornstein


4 Answers

"Except numbers that are divisible by 3 and 7 at the same time" can be broken down as follows:

"divisible by 3 and 7 at the same time" can be expressed as:

"(divisible by 3 and divisible by 7)"

"Except" can be expressed as "Not".

So you get:

Not (divisible by 3 and divisible by 7)

"divisible by 3" is (a % 3) == 0

"divisible by 7" is (a % 7) == 0

Giving:

Not ( (a % 3) == 0 and (a % 7) == 0)

In C# Not becomes ! and and becomes &&, so you can write the whole thing in C# as:

if (!((a % 3) == 0 && (a % 7) == 0))


Compare with your incorrect:

if (a % 3 != 0 && a % 7 != 0)

This latter is incorrect because it means:

if (the number is not divisible by 3) and (the number is not divisible by 7).

i.e. it means "Print the number if it is neither divisible by 3 nor divisible by 7", which means "don't print the number if it's divisible by 3 or 7".

To see why, first consider the number 6:

6 is not divisible by 3? = false (because 6 *is* divisible by 3)
6 is not divisible by 7? = true (because 6 is *not* divisible by 7)

So this resolves to if false and true which is, of course, false.

This result also applies to any other number divisible by 3, so no numbers divisible by 3 will be printed.

Now consider the number 14:

14 is not divisible by 3? = true (because 14 is *not* divisible by 3)
14 is not divisible by 7? = false (because 14 *is* divisible by 7)

So this resolves to if true and false which is, of course, false.

This result also applies to any other number divisible by 7, so no numbers divisible by 7 will be printed.

Hopefully you can see why it's wrong now. If not, consider this equivalent example:


Suppose we have four people, Tom the Carpenter, Dick the Carpenter, Harry the Butcher and Tom the Butcher.

This question is equivalent to the one you're asking:

 Name every person who is (not called Tom and is not a Butcher)

And you should be able to see that this the same as asking:

Name every person except (anyone called Tom or anyone who is a Butcher)

In both cases, the answer is Dick the Carpenter.

The question you should have asked is:

Name every person except (anyone called Tom who is also a butcher)

To which the answer is Tom the Carpenter, Dick the Carpenter and Harry the Butcher.


Footnote: De Morgan's laws

The second law states that:

"not (A or B)" is the same as "(not A) and (not B)"

This is the equivalent of my example above where:

Name every person except (anyone called Tom or anyone who is a Butcher)

is the equivalent to:

Name every person who is (not called Tom and is not a Butcher)

where A is anyone called Tom and B is anyone who is a butcher and not is written as except.

like image 54
Matthew Watson Avatar answered Nov 20 '22 05:11

Matthew Watson


You should read De Morgan's laws

"not (A and B)" is the same as "(not A) or (not B)"

also,

"not (A or B)" is the same as "(not A) and (not B)".

a % 3 != 0 && a % 7 != 0 is true when a is not divisible by 3 (a % 3 != 0) and not divisible by 7 (a % 7 != 0). So all as which are divisible by 3 or 7 (3,6,7,9,12,14,...) makes the whole expression false. You can rephrase it like !(a % 3 == 0 || a % 7 == 0)

like image 31
Hamid Pourjam Avatar answered Nov 20 '22 05:11

Hamid Pourjam


All you really need is:

if ((a%21) != 0) Console.WriteLine(a);

Explanation: The numbers that are divisible by both a and b are essentially the numbers divisible by the LCM of a and b. Since, 3 and 7 are prime number, you are basically looking for numbers that are not divisible by 3*7.

like image 9
displayName Avatar answered Nov 20 '22 05:11

displayName


Should be:

if ( !(a % 3 == 0 && a % 7 == 0) )
{
    Console.WriteLine(a);
}

It means exactly: all the numbers except for those that are divisible by 3 and 7 at the same time.

You could also rephrase it as:

if ( a % 3 != 0 || a % 7 != 0 )
{
    Console.WriteLine(a);
}
like image 9
user2622016 Avatar answered Nov 20 '22 04:11

user2622016