If Statement logic is not correct - c++

I have this if statement and it is not working:
if (pEntry->GetStudentMaterialStudyPoint(StudentAssign::kBibleReading) == 1 &&
(pEntry->GetStudentMaterialStudyPoint(StudentAssign::kItem1) == 1 && LOBYTE(LOWORD(pEntry->GetStudentAssignFlags()))) &&
(pEntry->GetStudentMaterialStudyPoint(StudentAssign::kItem2) == 1 && HIBYTE(LOWORD(pEntry->GetStudentAssignFlags()))) &&
(pEntry->GetStudentMaterialStudyPoint(StudentAssign::kItem3) == 1 && LOBYTE(HIWORD(pEntry->GetStudentAssignFlags()))) &&
(pEntry->GetStudentMaterialStudyPoint(StudentAssign::kItem4) == 1 && HIBYTE(HIWORD(pEntry->GetStudentAssignFlags()))))
{
MWBValidationErrorStruct errorMWBValidation;
errorMWBValidation.iDateIndex = iDateIndex;
errorMWBValidation.datMeeting = pEntry->GetMeetingDate();
errorMWBValidation.eValidationErrorType = CChristianLifeMinistryDefines::MWBValidationErrorType::MaterialStudyPoints;
m_listValidationErrors.push_back(errorMWBValidation);
}
}
I am trying to find out if all of the items have a value of 1. The first item (bible reading) will always be checked. But the items 1 to 4 only need to be checked if they are "included". That is what the LOBYTE(LOWORD(pEntry->GetStudentAssignFlags())) is for.
So,
Bible Reading - 1
Item 1 - 1
Item 2 - 1 - Not included
Item 3 - 1 - Not included
Item 4 - 1 - Not included
In the above scenario the if should be true because both BR and Item 1 are set to 1. We ignore the other 3 items.
Bible Reading - 1
Item 1 - 2
Item 2 - 3
Item 3 - 1 - Not included
Item 4 - 1 - Not included
In the above scenario the if should return false because all the values are not 1 and we are ignoring the last two items.
What is wrong with my if logic?

You should use (!included || x == 1) to ignore checking an item if it's not included. Because of short circuiting, if included is false, you won't even check the other side of the OR, which is exactly what you want.
Your if could look like:
if (pEntry->GetStudentMaterialStudyPoint(StudentAssign::kBibleReading) == 1 &&
(!LOBYTE(LOWORD(pEntry->GetStudentAssignFlags())) || pEntry->GetStudentMaterialStudyPoint(StudentAssign::kItem1) == 1) &&
...
This may be a little confusing, so let's make a truth table...
included | x | !included | x == 1 | (!included || x == 1)
------------------------------------------------------
false | 3 | true | false | true
true | 3 | false | false | false
true | 1 | false | true | true
If included = false, then !included will be true, so (!included || x == 1) will always be true. This is what we want--if we're not included, just evaluate to true without even checking x == 1.
If included = true, then !included is false, so the value of (!included || x == 1) will be whatever x == 1 is. Which is again what we want. If we're included, then depend on x == 1.

Related

Which of these answers are the equivalent of O_RDWR on Ubuntu 14.04 LTS?

I have been given a list of the following check box containing all possible solutions to the question of choosing all true answers equivalent to O_RDWR on Ubuntu 14.04 LTS. according to this list below
O_RDONLY
1
2
3
1 << 1
3 & 2
3 | 2
O_WRONLY
(O_RDONLY + O_WRONLY)
(O_RDONLY | O_WRONLY)
(O_RDONLY & O_WRONLY)
(O_RDONLY && O_WRONLY)
(O_RDONLY << 1)
(O_WRONLY << 1)
0
I have chosen 2 and (O_RDONLY | O_WRONLY) but am still getting errors
anyone who can help me with this?
O_WRONLY = 1, O_RDONLY = 0 and O_RDWR = 2 so do the bitwise and find which statement gives you 2
have you got it it means 2, 1<<1, 3&2 and (O_WRONLY<<1) these can give you 2
Look into bitwise operators.
O_RDWR is defined in fcntl.h and is equals to 2.
O_WRONLY = 1
O_RDONLY = 0
1 = 1
2 = 2
3 = 3
1 << 1 = 2
3 & 2 = 2
3 | 2 = 3
O_WRONLY = 1
(O_RDONLY + O_WRONLY) = 1
(O_RDONLY | O_WRONLY) = 1
(O_RDONLY & O_WRONLY) = 0
(O_RDONLY && O_WRONLY) = 0
(O_RDONLY << 1) = 1
(O_WRONLY << 1) = 2
0 = 0
None of them.
The only equivalent to O_RDWR is O_RDWR. O_RDWR is not a bitwise combination of individual bits. Neither are O_EXEC, O_RDONLY, O_SEARCH, or O_WRONLY.
Per the POSIX documentation for open() (bolding mine):
... Applications shall specify exactly one of the first five values
(file access modes) below in the value of oflag:
O_EXEC
Open for execute only (non-directory files). The result is unspecified if this
flag is applied to a directory.
O_RDONLY
Open for reading only.
O_RDWR
Open for reading and writing. The result is undefined if this flag is applied to a FIFO.
O_SEARCH
Open directory for search only. The result is unspecified if this flag is
applied to a non-directory file.
O_WRONLY
Open for writing only.
2,
1<<1 also 00000001 shift left by 1 = 00000010 so, the value also 2 ,
3&2 also 2,
O_WRONLY << 1 also 2,
so this is the answer
2, 1<<1 also 00000001 shift left by 1 = 00000010 so, the value also 2, 3&2 also 2, O_WRONLY << 1 also 2,
final answer :
2
1<<1
3&2
O_WRONLY << 1

From natural language to C++ expression

Assignment:
Translate the following natural language expressions to C++ expressions. Assume that all the variables are non-negative numbers or boolean (of value true or false).
Natural Language:
Either a and b are both false or c is true, but not both.
My solution:
(a==0 && b==0)xor(c==1)
Professors solution:
(!a && !b) != c
Questions:
I think I slightly understand the first bracket, by saying "not-a" and "not-b" I think that a and b must then be wrong, provided a b are assumed to be non-zero in the beginning. Right?
But what about the part that says "unequal to c"?
I don't understand the Professors solution, can anyone break it down for me?
Thank you for the help!
I'll assume that a, b and c are bool.
Let's draw some truth tables:
| a | !a | a==1 | a==0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 0 |
As you can see, a and a==1 are equivalent, and !a and a==0 are also equivalent, so we can rewrite (a==0 && b==0)xor(c==1) as (!a && !b) xor c.
Now some more truth tables:
| a | b | a xor b | a != b |
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 |
So a!=b is equivalent to a xor b, so we can rewrite (!a && !b) xor c to (!a && !b)!=c. As you see, your solutions are fully equivalent, just written with different 'signs'.
UPD: Forgot to mention. There are reasons why professor's solution looks exactly in that way.
The professor's solution is more idiomatic. While your solution is technically correct, it's not an idiomatic C++ code.
First little issue is usage of types. Your solution relies on conversion between int and bool when you compare boolean value to a number or use xor, which is a 'bit-wise exclusive or' operator acting on ints too. In a modern C++ it is much more appreciated to use values of correct types and not to rely on such conversions as they're sometimes not so clear and hard to reason about. For bool such values are true and false instead of 1 and 0 respectively. Also != is more appropriate than xor because while technically bools are stored as numbers, but sematically you haven't any numbers, just logical values.
Second issue is about idiomacy too. It lies here: a == 0. It is not considered a good practice to compare boolean expressions to boolean constants. As you already know, a == true is fully equivalent to just a, and a == false is just !a or not a (I prefer the latter). To understand the reason why that comparing isn't good just compare two code snippets and decide, which is clearer:
if (str.empty() == false) { ... }
vs
if (not str.empty()) { ... }
Think booleans, not bits
In summary, your professor's solution is better (but still wrong, strictly speaking, see further down) because it uses boolean operators instead of bitwise operators and treating booleans as integers. The expression c==1 to represent "c is true" is incorrect because if c may be a number (according to the stated assignment) then any non-zero value of c is to be regarded as representing true.
See this question on why it's better not to compare booleans with 0 or 1, even when it's safe to do so.
One very good reason not to use xor is that this is the bit-wise exclusive or operation. It happens to work in your example because both the left hand side and right hand side are boolean expressions that convert to 1 or 0 (see again 1).
The boolean exclusive-or is in fact !=.
Breaking down the expression
To understand your professor's solution better, it's easiest to replace the boolean operators with their "alternative token" equivalents, which turns it into better redable (imho) and completely equivalent C++ code:
Using 'not' for '!' and 'and' for '&&' you get
(not a and not b) != c
Unfortunately, there is no logical exclusive_or operator other than not_eq, which isn't helpful in this case.
If we break down the natural language expression:
Either a and b are both false or c is true, but not both.
first into a sentence about boolean propositions A and B:
Either A or B, but not both.
this translates into A != B (only for booleans, not for any type A and B).
Then proposition A was
a and b are both false
which can be stated as
a is false and b is false
which translates into (not a and not b), and finally
c is true
Which simply translates into c.
Combining them you get again (not a and not b) != c.
For further explanation how this expression then works, I defer to the truth tables that others have given in their answers.
You're both wrong
And if I may nitpick: The original assignment stated that a, b and c can be non-negative numbers, but did not unambiguously state that if they were numbers, they should be limited to the values 0 and 1. If any number that is not 0 represents true, as is customary, then the following code would yield a surprising answer:
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);
I will tryto explain with some more words: Numbers can be implicitly converted to boolean values:
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.
Source on cppreference
This leads to the following conclusions:
a == 0 is the same as !a, because a is converted to a boolean and then inverted, which equals !(a != 0). The same goes for b.
c==1 will become only true when c equals 1. Using the conversion (bool)c would yield true when c != 0 not just if c == 1. So it can work, because one usually uses the value 1 to represent true, but it's not garantued.
a != b is the same as a xor b when a and b ar boolean expressions. It's true, when one value or the other is true, but not both. In this case the left hand side (a==0 && b==0) is boolean, so the right hand side c is converted to boolean too, thus, both sides are interpreted as boolean expressions, thus != is the same as xor in this case.
You can check all of this yourself with the truthtables that the other answers provided.
As we can see from the truth tables:
!(not) and ==0 give the same results.
!= and xor give the same results.
c==1 is the same as just c
So one under the other, shows why these 2 expressions give the same result:
(a==0 && b==0) xor (c==1)
(!a && !b) != c
Truth tables :
Not
| | ! |
| 0 | 1 |
| 1 | 0 |
==0
| |==0|
| 0 | 1 |
| 1 | 0 |
==1
| |==1|
| 0 | 0 |
| 1 | 1 |
And
| a | b | && |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Not equal
| a | b | != |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
XOR
| a | b |xor|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |

DO IF, ELSE: Else not being computed

Only the initial if statement variable computation is being completed--the ELSE part is being ignored. Can someone explain why? Many thanks.
DATASET ACTIVATE DataSet1.
DO IF ((A1_SCN2_PR1_UE = 0 & A1_SCN3_PR1_UE = 0 & A1_SCN4_PR1_UE = 0 & A1_SCN5_PR1_UE = 0) |
(A2_SCN2_PR1_UE = 0 & A2_SCN3_PR1_UE = 0 & A2_SCN4_PR1_UE = 0 & A2_SCN5_PR1_UE = 0) |
(A3_SCN2_PR1_UE = 0 & A3_SCN3_PR1_UE = 0 & A3_SCN4_PR1_UE = 0 & A3_SCN5_PR1_UE = 0)).
Compute FM_zero = 1.
ELSE.
Compute FM_zero = 0.
End IF.
EXECUTE.
Not sure why your ELSE is not being computed, but I suggest you drop the DO IF and go this way instead:
compute FM_zero =
((A1_SCN2_PR1_UE = 0 & A1_SCN3_PR1_UE = 0 & A1_SCN4_PR1_UE = 0 & A1_SCN5_PR1_UE = 0) |
(A2_SCN2_PR1_UE = 0 & A2_SCN3_PR1_UE = 0 & A2_SCN4_PR1_UE = 0 & A2_SCN5_PR1_UE = 0) |
(A3_SCN2_PR1_UE = 0 & A3_SCN3_PR1_UE = 0 & A3_SCN4_PR1_UE = 0 & A3_SCN5_PR1_UE = 0)).
This will put a 1 in all true cases and 0 in all false cases.
SPSS uses three-valued logic: True, False, or don't know (sysmis).
From the Syntax Reference Manual...
Missing values returned by the logical expression on DO IF or on any ELSE IF cause control to pass to
the END IF command at that point.
So generally you should put the sysmis test first in your DO IF and follow with appropriate ELSE IF/ELSE.

C++ operators precedence

I am using this statement
if ((pm && pn) || (pm == false && pn == false))
it is supposed to return true only if both pm and pn are true or if both are false. But this is also returning true if only only first one (pm) is true.
So now it is acting like this:
0 0 = 1
0 1 = 0
1 0 = 1
1 1 = 1
but I need it to work like this:
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1
can you tell me where am I making mistake?
What you want is simply:
if (pm == pn)
You are checking if pm is true twice. You also need to check if both are the same, not whether they are both true. So,
if ((pm == pn)
^^ ^^
pm && pm
should be
pm && pn
^
The whole expression can be simplified to
pm == pn
if the variables already have bool type.
Why not try xor?
if (!(pm ^ pn)) { /*...*/ }
Or simply equal?
if (pm == pn) { /*...*/ }
if ((pm && pm) || (pm == false && pn == false))
it is supposed to return true only if both pm and pn are true or if both are false. But this is also returning true if only only first one (pm) is true.
Because you made a typo. You meant pm && pn.
Instead just write if (pm == pn), which is equivalent along as the only semantic values are indeed true and false for both variables.
Plus, consider making your variable names clearer and more distinct.
Note that operator precedence has nothing to do with this.
Since the question's title asks about precedence, note that || has lower precedence than &&. So the two sets of inner parentheses are redundant, and the original expression is just a longer way of saying
if (pm && pm || pm == false && pn == false)
Now, fixing the obvious typo:
if (pm && pn || pm == false && pn == false)
Removing the unneeded explicit comparisons:
if (pm && pn || !pm && !pn)
And, finally, a less obvious transformation, which others have suggested:
if (pm == pn)

Regex Negations in Vim

Question:
How do I convert var x+=1+2+3+(5+6+7) to var x += 1 + 2 + 3 + ( 5 + 6 + 7 )
Details:
Using regular expressions, something like :%s/+/\ x\ /g won't work because it will convert += to + = (amongst other problems). So instead one would use negations (negatives, nots, whatever they're called) like so :%s/\s\#!+/\ +/g, which is about as complicated a way as one can say "plus sign without an empty space before it". But now this converts something like x++ into x + +. What I need is something more complex. I need more than one constraint in the negation, and an additional constraint afterwards. Something like so, but this doesn't work :%s/[\s+]\#!+\x\#!/\ +/g
Could someone please provide the one, or possibly two regex statements which will pad out an example operator, such that I can model the rest of my rules on it/them.
Motivation:
I find beautifiers for languages like javascript or PHP don't give me full control (see here). Therefore, I am attempting to use regex to carry out the following conversions:
foo(1,2,3,4) → foo( 1, 2, 3, 4 )
var x=1*2*3 → var x = 1 * 2 * 3
var x=1%2%3 → var x = 1 % 2 % 3
var x=a&&b&&c → var x = a && b && c
var x=a&b&c → var x = a & b & c
Any feedback would also be appreciated
Thanks to the great feedback, I now have a regular expression like so to work from. I am running these two regular expressions:
:%s/\(\w\)\([+\-*\/%|&~)=]\)/\1\ \2/g
:%s/\([+\-*\/%|&~,(=]\)\(\w\)/\1\ \2/g
And it is working fairly well. Here are some results.
(1+2+3+4,1+2+3+4,1+2+3+4) --> ( 1 + 2 + 3 + 4, 1 + 2 + 3 + 4, 1 + 2 + 3 + 4 )
(1-2-3-4,1-2-3-4,1-2-3-4) --> ( 1 - 2 - 3 - 4, 1 - 2 - 3 - 4, 1 - 2 - 3 - 4 )
(1*2*3*4,1*2*3*4,1*2*3*4) --> ( 1 * 2 * 3 * 4, 1 * 2 * 3 * 4, 1 * 2 * 3 * 4 )
(1/2/3/4,1/2/3/4,1/2/3/4) --> ( 1 / 2 / 3 / 4, 1 / 2 / 3 / 4, 1 / 2 / 3 / 4 )
(1%2%3%4,1%2%3%4,1%2%3%4) --> ( 1 % 2 % 3 % 4, 1 % 2 % 3 % 4, 1 % 2 % 3 % 4 )
(1|2|3|4,1|2|3|4,1|2|3|4) --> ( 1 | 2 | 3 | 4, 1 | 2 | 3 | 4, 1 | 2 | 3 | 4 )
(1&2&3&4,1&2&3&4,1&2&3&4) --> ( 1 & 2 & 3 & 4, 1 & 2 & 3 & 4, 1 & 2 & 3 & 4 )
(1~2~3~4,1~2~3~4,1~2~3~4) --> ( 1 ~ 2 ~ 3 ~ 4, 1 ~ 2 ~ 3 ~ 4, 1 ~ 2 ~ 3 ~ 4 )
(1&&2&&3&&4,1&&2&&3&&4,1&&2&&3&&4) --> ( 1 && 2 && 3 && 4, 1 && 2 && 3 && 4, 1 && 2 && 3 && 4 )
(1||2||3||4,1||2||3||4,1||2||3||4) --> ( 1 || 2 || 3 || 4, 1 || 2 || 3 || 4, 1 || 2 || 3 || 4 )
var x=1+(2+(3+4*(965%(123/(456-789))))); --> var x = 1 +( 2 +( 3 + 4 *( 965 %( 123 /( 456 - 789 )))));
It seems to work fine for everything except nested brackets. If I fix the nested brackets problem, I will update it here.