An interview question on conditional operator - c++

I recently encountered with this question: How to reduce this expression: s>73?61:60;.
The hint given was that Instead of using conditional operator we could use a simple comparison which will work fine.
I am not sure but I think it is possible with some GCC extension,although I am unable to figure it out myself.
EDIT:The whole expression is this : s-=s>73?61:60

Just like the other answers:
s -= (s > 73) + 60;
This expression works because the spec defines the results of the relational operators. Section 6.5.8 paragraph 6:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int.

How to reduce this expression: s-=s>73?61:60;
How about:
typedef int Price;
Price getPriceAfterRebate(const Price priceBeforeRebate)
{
const Price normalRebate = 60;
const Price superRebate = 61;
const Price superRebateThreshold = 73;
Price returnValue = priceBeforeRebate;
if (priceBeforeRebate > superRebateThreshold)
{
returnValue -= superRebate;
}
else
{
returnValue -= normalRebate;
}
return returnValue;
}
Tada! An ugly piece of unmaintainable code is reduced to a readable and maintainable block of code.

This is such an ugly piece of code that I can't beleive I wrote it, but I think it fulfills the requirement:
My answer to the original question which was s>5?6:9:
9 - (((int)(s > 5)) * 3)
Rewritten for the updated question:
61 - (int)(s > 73)

Maybe this?
60 + !!(s > 73)
The double-bang maps non-zero values to 1 and zero to zero.

What is the value of (s>5)? Could you do some arithmetic with that?
Without the hint, I would say this was a bad "gotcha" interview question that requires a particular a-ha insight that's not correlated with ability. With the hint, it's... nice, but dim.

If we assume that True = 1 and False = 0, then doesn't this work:
s-= (60 + (s > 73))

It can be thought of as s -= (s > 73) + 60 as > is a relational operator and it will return 1 or 0 depending on result of expression s > 73 ,As the return value is int so it will work fine

Related

Converting if-else to for loop

int max_range = 100;
// I do not want to add more else if.. Actually max range is still 100 with more else ifs.
// Range can take values from 0 to 100
if (range <= 10){
a[0]= value;
}
else if (range > 10 && range <= 20){
a[1]= value;
}
else if (range> 20 && range <= 30){
a[2]= value;
}
else if (range > 30 && range <= 40){
a[3]= value;
}
else if (range> 40 && <= max_range){
a[4]= value;
}
It is simple code. I would like it to remove the nested else if's and use a for loop.
How can I convert this into a for loop?
You don't need a loop, you are doing one action.
a[std::max(0, std::min(4, (range - 1) / 10))] = value;
My other answer is very particular to the boundaries being multiples of 10. A runtime modifiable version would be something like
std::set<int> boundaries = { 10, 20, 30, 40, max_range };
// ... potentially modify `a` and `boundaries`, keeping the number of elements equal
a[std::distance(boundaries.begin(), boundaries.lower_bound(range))] = value
I would like it to remove the nested else if's and use a for loop Probably incorrect expression: There's no nested if-else in your example.
Loops, if-else and switch work differently however they all handle conditions:
Loops do iteration; Checking for some condition n times whereas if, switch they check once. So you cannot convert a if-else into a loop.
It's really a good programming trying to make the code effective and as smaller as possible but it is not always the case. If so why such experts build a huge programs with maybe millions of code lines.
Your code works fine.

I just created an extremely fast way to sort primes. How do I improve it?

Basically, how it works is it converts a number into a string, and if it finds any even in the string then it gives foundEven variable a positive value. The same goes for odd numbers.
(One thing I don't get is why if I switch the '>' sign with an '<' in if (FoundEvenSignedInt < FoundOddSignedInt) it gives you the correct result of an odd number.)
Are there any ways I could improve the code? Are there any bugs in it? I'm fairly new at C++ programing.
#include <string>
#include <cstddef>
int IsPrime(long double a)
{
int var;
long double AVar = a;
signed int FoundEvenSignedInt, FoundOddSignedInt;
std::string str = std::to_string(a);
std::size_t foundEven = str.find_last_of("2468");
std::size_t foundOdd = str.find_last_of("3579");
FoundEvenSignedInt = foundEven;
FoundOddSignedInt = foundOdd;
if (FoundEvenSignedInt < FoundOddSignedInt)
{
var = 1;
goto EndOfIsPrimeFunction;
}
if (FoundEvenSignedInt > FoundOddSignedInt)
{
var = 2;
goto EndOfIsPrimeFunction;
}
// This if statement kept giving me this weird warning so I made it like this
if (FoundEvenSignedInt == -1)
{
if (FoundOddSignedInt == -1)
{
if (AVar == 10 || 100 || 1000 || 10000 || 100000 || 1000000)
{
var = 2;
goto EndOfIsPrimeFunction;
}
}
}
EndOfIsPrimeFunction:
return var;
}
Here are some ways to improve the code.
The Collatz conjecture is about integers. long double is a data type of floating point numbers. It is unsuitable for checking the conjecture. You need to work with an integral data type such as unsigned long long. If this doesn't have enough range for you, you need to work with some kind of Bignum dat atype. There isn't any in the standard C library, you need to find a third party one.
The Collatz conjecture has nothing to do with being prime. It is about even and odd integers. It is true that all prime numbers except 2 are odd, but this fact doesn't help you.
The data type to answer yes/no questions in C++ is bool. By convention. for any other numeric data type zero means "no" and all other values mean "yes" (technically, when converted to bool, zero is converted to false and other values to true, so you can do things like if (a % 2). A function that returns 1 and 2 for yes and no is highly unconventional.
A natural method of checking whether a number is odd is this:
bool isOdd (unsigned long long a)
{
return a % 2;
}
It is somewhat faster than your code (by a factor of about 400 on my computer), gives correct results every time, is readable, and has zero goto statements.
Instead of the if(AVar == 10 || 100 || ..., you can say if(!(AVar % 10)).

C++ Error "lvalue required as left operand of assignment"

I am new to C++ and I have a problem where i have to transform a pseudocode in C++ / C / Pascal language. The answer at the end of the book written in Pascal.
The problem in my C++ code is that at the line 12, I get the error which can be found in the title. Any idea?
Pascal Code:
var n,x:integer;
begin
n:=0;
repeat
write('x=');read(X);
if x<>0 then
if x mod 5 = 0 then
n:=n+1
else
n:=n-1;
until x=0;
if n=0 then
write('yes')
else
write('no')
end;
My C++ Code:
int main()
{
int x,n;
cin>>x;
while(x>0)
{
if(x>0)
{
if(x%5=0){
n=n+1;
} else {
n=n-1;
}
}
if(n=0){
cout<<"Yes"<<;
} else {
cout<<"No"<<;
}
}
}
You have a simple typo: if(x%5=0){ is an attempt to assign 0 to x % 5 (due to operator precedence modulus is computed before assignment). x % 5 cannot be assigned to (it's not an lvalue) and the compiler is telling you that.
The fix, of course, is to write x % 5 == 0.
You're lucky in this case that the error is picked up at compile-time. Something like if (n = 0) (on line 18) might not be, since x = 0 is an expression with value 0.
Two ways to guard against that:
Ensure that your compiler warnings are as aggressive as you can bear. With gcc, I use -Wall -Wextra, and that combination is enough to catch this common problem.
Some developers will write if (0 == x) since an errant if (0 = x) would be picked up at compile time as an attempt to assign to 0. Personally, I find that obfuscating.
Assignment operator requires lvalue means the left side operand need to be a variable/location that can hold a value.
This is what is meant by the error.
What you need in your if statement is == likely not assignment as mentioned by other answers
You need to use == in conditions (while, if, ...) for equality check in C++.
if(x%5 = 0)
should be
if(x%5 == 0)
"x%5" is not an lvalue in that you can not assign a value to it, hence the error.

For Loops for a Time Class

I am trying to write a for loop for a time class. Where if the minutes entered are over 60, 60 is subtracted from the total minutes and hours is incremented by 1 until the final minutes left is less than 60 . I was doing if statements like
if (m > 59){
m = m - 60;
h++;
if (m > 59)... etc..
but that doesn't cover every case and I feel like I should know how to do this for loop but I can't figure it out. Any help would be appreciated, thanks
Well if it doesn't have to be implemented using loops, you could do simply
h = m / 60;
m = m % 60;
It is the fastest and cleanest way to do that, I suppose.
Not really sure whether you want to do anything else inside the loops. If so, this won't help you very much.
Edit:
Here is some explanation of how it works.
What m / 60 does is called integer division. It returns floor of the expression. So for example if m = 131 than m / 60 = 2.
The second expression uses the modulo operator. Basically it finds the reminder after division. Back to our example, m % 60 = 11 since m can be written as m = 60 * 2 + 11 = 131. For further information please refer to wiki.
#Jendas has a good simple answer to the overall problem, but if you want to keep with this format but fix your issue with loops, you could put the whole thing in a while loop instead of individual if statements:
while(m >59)
{
m = m - 60;
h++;
// do anything else you need to take care of
}
// finishing statements
h = 0;
while (m >= 60)
{
m = m - 60;
h++;
}
You probably want to use >= 60 instead of 59.
Also, as Jendas rightly suggested you might want to research a little about the modulus operator '%'

Which side (left or right) of && (and) operator evaluated in C++

Which order is the and && operator evaluated
For example the following code
if (float alpha = value1-value2 && alpha > 0.001)
//do something
threw an exception that alpha is being used without being initiated.
I thought the expression left of the && would always initiate the value of alpha first, but it seems I may be wrong
Any idea?
Thanks
This gets parsed as:
if (int alpha = (value1-value2 && (alpha > 0.001)))
... because && has a higher "parsing precedence" than = -- which is probably not what you want. Try:
int alpha = value1-value2;
if (alpha && (alpha > 0.001))
The bottom line here is that what you are trying to express cannot be possibly expressed by a single logical condition with the declaration of alpha being embedded into it (despite what some other answers claim).
The other answers already explained to you that your condition is not parsed the way you think it is parsed, although many answers make an obvious error of referring to the precedence of = operator in the condition, while in reality there's no = operator there whatsoever. The correct explanation is that when you declare a variable in the if condition, the syntax is that of declaration with an initializer, so the whole thing is parsed the same way as
int alpha = value1 - value2 && alpha > 0.001;
would be parsed, i.e. it is a declaration of int alpha initialized with value1 - value2 && alpha > 0.001. There's no operator = in it. And I hope now you can see why the compiler says that you are reading an uninitialized variable in the initializer expression. The compiler would make the same complaint on the following declaration
int alpha = alpha; // reading uninitialized variable
for the very same reason.
To achieve what you are literally trying to express, you have to either pre-declare alpha
int alpha;
if ((alpha = value1 - value2) && alpha > 0.001) {
// whatever
}
or split your if into two
if (int alpha = value1 - value2)
if (alpha > 0.001) {
// whatever
}
However, since the second condition already requires alpha to be greater than 0, it doesn't make much sense to even verify the first one, so the most meaningful thing to do would be to just reduce the whole thing to
int alpha = value1 - value2;
if (alpha > 0.001) {
// whatever
}
Of course, as others already noted, the comparison of an int value to 0.001 is a valid, but rather weird thing to do. Just do
int alpha = value1 - value2;
if (alpha > 0) {
// whatever
}
The left side is always evaluated first. The problem here is operator precedence. See if this doesn't work better:
if ((int alpha = value1-value2) && (alpha > 0.001))
After clarifying how it works (for educative purposes), do not do this. Do not mix variable initialization/assignment and comparisons in the same statement.
It is better if each statement is either a "command" or a "query" alone.
And it is much, much better if a condition inside an "if" is very clearly readable, and unequivocally bool. Not integer, no nothing, just bool.
The first part of your condition is an integer. Then you do an and with a bool. You are forcing a conversion with no need at all. Give if's and conditional operators exactly what they ask for: bools.
Answering the question in the title, it depends on the types of the operands.
For builtin-types, && short-circuits, meaning that the LHS is evaluated, and if it is false then the RHS is not evaluated at all.
For user-defined types which have overloaded operator&&, it does not short-circuit. Both sides are evaluated, in unspecified order, and then the function is called.
I think others have handled the question you need answered, though.
If I'm not mistaken, that operation is undefined. Asigning to to variable and then referring to that same variable in a single statement is undefined.
I generally always use parenthesis just to make my code a little more clear of my intent.
It's evaluated from left to right.
In your case, however the assignment is the last thing to happen and they whole thing would behave as (where alpha is used as part of the calculation to get the result to initialize it):
if (int alpha = (value1-value2 && alpha > 0.001))
You can't mix variable declarations into complex expressions, therefore the following won't compile:
if ((int alpha = value1-value2) && (alpha > 0.001))
Therefore you'll need to split it up to two lines:
int alpha = value1 - value2;
if (alpha > 0.001)
if (int alpha = value1-value2 && alpha > 0.001)
According to the rules would be evaluated in order as
1. (value1-value2) [evaluate subtraction]
2. && (left side) [test left side]
3. (alpha > 0.001) [evaluated only if value-value2 != 0]
4. && (right side) [test right side]
4. alpha = [assignment]
In step 3, alpha is first evaluated. Since it hasn't been assigned—and maybe not declared, the rules aren't clear on this—it produces an error.
The flaw is that assignment is lower precedence than &&. What still doesn't work, but is closer:
if (int alpha = value1-value2, alpha > 0.001)
Gcc gives error: expected expression before ‘int’. Well maybe it's not closer. With the original statement, gcc says the same thing.
My guess is that it's because you're declaring the storage inside the "if" statement. I didn't even think that would compile.
Try this.
int alpha;
if ((alpha=value1-value2) && alpha>0.001)
But I don't think this is doing what you need. You have alpha as an int, and you're then comparing it to a floating point value. The first part of the && statement will retrun true as long as alpha is not zero and the second part will return true if alpha is greater than 0. So you should probably do this
int alpha;
if ((alpha=value1-value2)>0)
or for much more readable code
int alpha=value1-value2
if (alpha>0)
But to answer your original question: && is executed left to right and short circuited when the answer is obvious. I.e., if the first part of the && is false, the second isn't even evaulated!
Here's an article listing operator precedence and associativity.
From what I can tell, your intent is to declare a temporary, assign it the value of value1-value2, then test the result and enter the if block if it is greater than some value. alpha is being declares as an int, but you seem to be comparing it against a double. alpha should be a double.
Your'e being creative with the use of temporaries. Clear is often better than cute. Do this instead:
double alpha = value1-value2;
if (alpha > 0.001)
According to :
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
- LtR
> LtR
&& LtR
= RtL
given your example
(int alpha = value1-value2 && alpha > 0.001)
(int alpha = (value1-value2) && alpha > 0.001)
(int alpha = (value1-value2) && (alpha > 0.001))
(int alpha = (value1-value2) && (alpha > 0.001))
(int alpha = ((value1-value2) && (alpha > 0.001)))
As written this expression does the following:
Evaluates value1 - value2 and converts it to a bool by implicit comparison against zero - i.e., it is effectively (value1 - value2) != 0
Evaluates alpha > 0.001 after truncating 0.001 to int(0). At this point alpha is not initialized.
Calculates the Logical AND of the previous two evaluations
Converts the Boolean result of the Logical AND back to an integer
I think that this summarizes the rest of the posts. The only reason that I posted a separate answer is that I could not find one that mentioned both when alpha was not initialized and all of the conversions that are occurring here; wallyk's answer is closest.
Of course, the rest of the answers that suggest that you use parentheses and a separate declaration of alpha are exactly what you should do to fix this. Declaring variables within an if statement is part of the language that I haven't found a good use for - declarations within repetition structures seems more appropriate.
The problem is that the statement is evaluating like this:
if (int alpha = (value1-value2 && alpha > 0.001))
Use parentheses to fix the left- and right-hand sides of the && operator:
if ((int alpha = value1-value2) && (alpha > 0.001))