C++ hates me

MrColin

Platinum Member
May 21, 2003
2,403
3
81
I've been wanting to learn C++ for a long time and I've started on several books and tutorials. The lack of appropriate problems to practice on has held me back until today I when discovered Project Euler.

Problem 1 was pretty easy and I came up with this in a couple of minutes and it gives the correct answer:
Code:
int num = 1;
double sum = 0;
for (num = 1; num < 1000; num++)
    if ((num % 3) == 0){
        sum = sum + num;}
    else if ((num % 5) == 0){
        sum = sum + num;}
cout << "the answer is: " << sum;}

Of course I'm not satisfied just getting the correct answer, I wanted to reduce the # of LOC and make it more elegant and maybe get a quicker execution time so I paired it down to this:
Code:
int sum = 0;
for (int num = 1; num < 1000; num++)
    if ((num % 3)||(num % 5) == 0){
        sum += num;}
cout << "the answer is: " << sum;}
Which is smaller but gives the wrong answer and evidently is not logically the same but I don't see how.

The key difference being
Code:
if ((num % 3)||(num % 5) == 0){...}
is apparently not the same as
Code:
if ((num % 3) == 0){...}
else if ((num % 5) == 0){...}
I don't see why though, can anyone give me any hints why these aren't equivalent? Any other tips on C++ are also welcome.
 

Tweak155

Lifer
Sep 23, 2003
11,449
264
126
(num % 3) will always be true when it isn't 0, thus making the statement true when you don't want it to be. You need to set each statement == 0.

So:

if ((num % 3)||(num % 5) == 0)

becomes:

if ((num % 3) == 0 || (num % 5) == 0)

EDIT:

To be more clear, anything separated by || or && is its own statement. So it is simply evaluating (num % 3).

EDIT EDIT:

And as a tip, I like surrounding everything in parenthesis so I can specify what order items need to be executed, so there is no confusion as to what is being evaluated. It makes for messy code sometimes but it helps identify these types of issues. Otherwise the compiler will decide for you.
 
Last edited:

Crusty

Lifer
Sep 30, 2001
12,684
2
81
Code:
if (num % 3 == 0 || num % 5 == 0) {
}

You forgot the == 0 in the first part of your if.
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
To elaborate on what Tweak155 said, C and C++ will consider anything which evaluates to a non-zero number as "true". This can cause problems because so many things will implicitly evaluate to non-zero.

In your case it was probably just a simple misunderstanding of how multiple comparisons are written, but your mistake was perfectly ok with the compiler. For example, if you meant to type ==, but accidentally type and put:

Code:
int i;
...
if (i = 10) {...}

The compiler again won't complain, because it essentially sees

Code:
i = 10;
if (i) // this is implied to be "if (i != 0)"
{...}

You can avoid that one by getting in the habit of putting constants first, such as "10 == i". If you make a typo then, "10 = i" will generate a compile error (why? you can only do assignment to an lvalue, or something that actually has an address in memory. 10 is a constant, so it has no memory location, making it an rvalue).

tl;dr C++ is fun, but it hands you a loaded .44 Magnum and begs you to shoot your own foot off. :)
 

Paul98

Diamond Member
Jan 31, 2010
3,732
199
106
I've been wanting to learn C++ for a long time and I've started on several books and tutorials. The lack of appropriate problems to practice on has held me back until today I when discovered Project Euler.

Problem 1 was pretty easy and I came up with this in a couple of minutes and it gives the correct answer:
Code:
int num = 1;
double sum = 0;
for (num = 1; num < 1000; num++)
    if ((num % 3) == 0){
        sum = sum + num;}
    else if ((num % 5) == 0){
        sum = sum + num;}
cout << "the answer is: " << sum;}

Of course I'm not satisfied just getting the correct answer, I wanted to reduce the # of LOC and make it more elegant and maybe get a quicker execution time so I paired it down to this:
Code:
int sum = 0;
for (int num = 1; num < 1000; num++)
    if ((num % 3)||(num % 5) == 0){
        sum += num;}
cout << "the answer is: " << sum;}
Which is smaller but gives the wrong answer and evidently is not logically the same but I don't see how.

The key difference being
Code:
if ((num % 3)||(num % 5) == 0){...}
is apparently not the same as
Code:
if ((num % 3) == 0){...}
else if ((num % 5) == 0){...}
I don't see why though, can anyone give me any hints why these aren't equivalent? Any other tips on C++ are also welcome.

num % 3 will always be true since you don't compare it to anything
 

MrColin

Platinum Member
May 21, 2003
2,403
3
81
tl;dr C++ is fun, but it hands you a loaded .44 Magnum and begs you to shoot your own foot off.

I think that's part of why I'm so attracted to it over some other languages. Thanks everybody for the explanations.
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
> num % 3 will always be true since you don't compare it to anything

Actually in C/C++,
if ( n % 3 ) ...
is perfectly legal code and the same as
if ((n % 3 ) != 0) ...

It will be false for 0, 3, 6, 9, 12... and true for 1,2,4,5,7,8....

I'd always include the != 0 for clarity though.
 

MrColin

Platinum Member
May 21, 2003
2,403
3
81
> num % 3 will always be true since you don't compare it to anything

Actually in C/C++,
if ( n % 3 ) ...
is perfectly legal code and the same as
if ((n % 3 ) != 0) ...

It will be false for 0, 3, 6, 9, 12... and true for 1,2,4,5,7,8....

I'd always include the != 0 for clarity though.

Good points, thank you!