• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

C++ hates me

MrColin

Platinum Member
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 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:
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. 🙂
 
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
 
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.
 
> 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.
 
> 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!
 
Back
Top