C multiple operations in single row - c

I would like to do this in one line (C programming language):
int x = index >> 8;
int y = x < 10 ? x+1 : x+2;
Is it possible? How do I reference to value before ? sign, if I don't have it stored in separate integer?
"int y = (index >> 8) < 10 ? [what]+1 : [what]+2;"

You simply need to repeat the expression:
int y = (index >> 8) < 10 ? (index >> 8) + 1 : (index >> 8) + 2;
It's not very nice, or readable, so I don't get why you must do it this way. There's no built-in way in the language to reference the expression before the ?. Since expressions can have side-effects in C, it would be quite hairy if there was.

The way you have this expression is the best you can get there without code repetition.
If you absolutely need it to be a single string, you can simply do the following:
int y = (index >> 8) < 10 ? (index >> 8)+1 : (index >> 8)+2;

Because C makes no distinction between whitespace characters, you can have it in a single line:
int x = index >> 8; int y = x < 10 ? x+1 : x+2;
...which is completely valid C.
However your y and x values are not inter-dependent, so you can simplify the expression to just y:
int y = index >> 8; y = y < 10 ? y+1 : y+2;
If your y already exists, you can make use of the little-used comma operator to eliminate the semi-colon and reduce it to a single statement:
y = ( y = index >> 8 ), y < 10 ? y+1 : y+2;
Note that you cannot use the comma operator inside a value declaration statement because in that context it becomes the sequence separator.

It is generally not useful to try to optimize source code in this way. C does not specify what specific operations the computer must perform; C specifies what results a program must achieve. (By means of the “as if” model in C. The program the compiler produces must produce results as if you stepped through the specific operations you wrote, but those results can actually be obtained by any sequence of instructions the implementation chooses. The program only needs to reproduce results, not mechanisms.)
Generally, you should write your code to be clear, and you should allow the optimizer in the compiler to do its job of performing the calculations efficiently.

It is possible using this form :
int y = (y = index >> 8) < 10 ? y+1 : y+2;
Here, y get assigned the temporary value of index >> 8, so you can reuse that value after the ? operator.
And contrary to David's similar answer, this form work inside a value declaration statement as well.

Alternatively, by removing the ternary. The shift being equivalent to a division by 256, we can compare the value also before the shifting.
int y = (index >> 8) + 1 + (index >= 2560);
Of course, index should be positive for this to work.
EDIT: the expression has also the advantage of having no temporary write access and no sequence point.

Related

Does macro function with operator precedence show unusual result?

#define SQUARE(x,y) (x<y?x:y)
int a = 5, b = 6, c = 3;
int var = SQUARE(a & c,b);
I have searched and learnt that '<' precede '&'. As per rules it should give '5'. But it is giving output as '1'. But in some cases it is giving right output. Can you please explain macro rules of this and what am I missing here.
Macros are just replaced by the preprocessor, so the arguments are not evaluated and then passed like in functions.
In your example the expression SQUARE(a & c, b); will become (a & c < b ? a & c : b);
For a=5, b=6, c=3 it evaluates to:
(5 & 3<6 ? 5&3 : 6) //'<' precede '&' as you correctly mentioned
(5&1 ? 5&3 : 6) // '3 < 6' is a boolean expression which evaluates to 1. '&' is bitwise AND.
(1 ? 1 : 6)
(1)
So 1 is the right output.
EDIT:
A good aproach is to always use parentheses around your arguments and the whole expression to eliminate the problem of operator precedence.
As mention by others it can be dangerous to use macros due to multiple evaluation, which may not only effect performance.
For example:
#define SQUARE(x) ((x)*(x))
seems to only square the argument, but if you call it like
f = SQUARE(x++);
you will get undefined behaviour. A better approach for small function would be to declare it as inline.
inline int square(int x)
{
return x*x;
}
Also as mentioned by #EricPostpischil macros are not a textual replacement as the preprocessor replaces by tokens.
For example:
#define a 1
#define b 2
printf("%d\n", ab);
here ab is not replaced with 12 as someone would expect for pure textual replacement.
Macros require parentheses as they are not functions and just do the textual replacement
#define SQUARE(x,y) (((x)<(y))?(x):(y))
The macro is extremely side effects error and UB prone:
Example: SQUATE(x++,y)
in your example 5 & 3 will be evaluated every time you have the x in your macro. It will be less effective than the inline function
inline unsigned SQUARE(unsigned x, unsigned y)
{
return (x < y) ? x : y;
}
In a bit more detail, as #P__J__ said, macros are just text replacement by the pre-processor, not functions. So this:
#define SQUARE(x,y) (x<y?x:y)
int a = 5, b = 6, c = 3;
int var = SQUARE(a & c,b);
is translated to:
int a = 5, b = 6, c = 3;
int var = (a & c<b?a & c:b);
Because every x is replaced with a & c and every y is replaced with b.
If you also apply the values as in #Osiris 's answer, you'll get:
int var = (5 & 3 < 6 ? 5 & 3 : 6);
At this point, as you already said, < takes precedence over &.
The result of < is true or false, which means 1 or 0, so 3 < 6 becomes 1.
The result of & is the bitwise AND between two numbers, which in this case is also 1 (because 5 is 101 and 3 is 011).
This is why it becomes
(5 & 1 ? 1 : 6)
That next 5 & 1 will also become 1 (because of the AND between 101 and 001), so you'll get:
(1 ? 1 : 6)
And since 1 is true, you'll get the first value, which is also a 1.
Also, as already pointed out, be careful with evaluation in a macro.
These are just numbers and you're already seeing some not so obvious behaviour, but if had passed a function as one of the arguments, that function would've run multiple times.
For example
#define SQUARE(x,y) (x<y?x:y)
int var = SQUARE(update_counter(a), 1);
would have been translated to
int var = (update_counter(a) < 1 ? update_counter(a) : 1);
Thus potentially updating a hypothetical counter twice.

Rewriting a piece of C code without conditional statements or operators?

I was in a technical interview where the interviewer gave me a piece of code like this
int a=1;
a++;
...something..
...something.
if(a==25)
a=0;
he said me to rewrite this code without using switch,if else or ternary operator for the if condition. How it can be done?
It's quite simple actually:
a *= (a != 25);
This will multiply a by 0 if a is equal to 25, else it will multiply a by 1.
If you're also not allowed to test for equality then here is a fully arithmetic way:
unsigned int v = a - 25;
/* test for bits set and put result in lsb of v */
v |= v >> 16;
v |= v >> 8;
v |= v >> 4;
v |= v >> 2;
v |= v >> 1;
/* set a to a if lsb of v is 1, else set to 0 */
a *= v & 1;
a != 25 || (a = 0);
This does not use "switch,if else or ternary operator"
The question, as posed, gives undefined behaviour since you are using an uninitialised variable. Therefore you are free to write any code you like (so long as it compiles).
See C standard 6.3.2.1p2:
If the lvalue designates an object of automatic storage duration that
could have been declared with the register storage class (never had
its address taken), and that object is uninitialized (not declared
with an initializer and no assignment to it has been performed prior
to use), the behavior is undefined.
That, in my opinion, is the smart answer: although you would be wise to be graceful when answering a question in this way.
Remember that assignment is just an ordinary expression, and as such can be used as part of another expression. For example you could use the short-circuit logical and operator:
a == 25 && (a = 0);
You need to put parenthesis around the assignment because assignment has lower precedence than the && operator.
Another interesting answer could be
for ( ; a == 25 ; ) {
a = 0; break;
}
This does not use 'if-else', 'switch' or 'ternary operator'
If the context implied is a counting loop where a always repeats the cycle 0..24, then perhaps a mathematically more appealing solution would be
a = (a+1) % 25;
But this of course wouldn't work in a sitation where a can be anything, and it should only be reset in case of a==25, while something a==26 should be left alone.
The interviewers might like it though, if you search for a "semantic" solution like that, and can explain when to use this.
I think interviewer wanted you to use this line instead of if:
a %= 25;

What is the difference between increment operator(++) and addition (+) operator?

What is the difference between increment operator ++ and an addition + operator? Why can't we can use + instead of ++?
What are the advantages of ++/-- operators over +/-? Where exactly are they applicable?
x++;
v.s.
x = x + 1;
The main advantage comes from pre-increment v.s. post increment:
e.g.
x = 1;
y = 1;
a = x + 1; // a is 2, x is 1 - e.g. does not modify x
a = ++x; // a is 1, x is 2
b = y++; // b is 2, y is 2
The major downside is that stuff like
a = ++x + x--;
is undefined behavior. Completely compiler dependent and WILL make life hell for anyone trying to figure out the "bug".
The only difference that is given by the C standard is the number of evaluations of x. For normal variables the difference usually doesn't matter. If the compiler can prove that in x = x + 1 the two evaluations of x should give the same value it might optimize this out.
If x is e.g declared volatile or involves the evaluation of a function, the evaluation must be done twice. Example:
unsigned* f(void);
then
*f() = *f() + 1;
is quite different from
++(*f());
The unary operators (++, --) are mainly there for convenience - it's easier to write x++ than it is to write x = x + 1 for example.
++ can also be used to do a 'pre-increment' or a 'post-increment'. If you write x++ then the value of x is increased and the original value of x is returned. For example:
int a = 0;
int x = 0;
a = x++; // x is now equal to 1, but a is equal to 0.
If you write ++x, x is still incremented, but the new value is returned:
int a = 0;
int x = 0;
a = ++x; // Both a and x now equal 1.
There is also usually a minor difference in the compiler's implementation as well. Post-increment (x++) will do something like this:
Create a temporary variable
Copy x to the temporary variable
Increment x
Return the temporary variable
Whereas pre-increment (++x) will do something like this:
Increment x
Return x
So using pre-increment requires less operations than post-increment, but in modern day systems this usually makes no worthwile difference to be a decent way of optimising code.
You could in fact use addition:
a = a + 1
But most people prefer the shorter version. In some languages it actually avoids the need to copy the value to a new location, but as nneonneo has helpfully pointed out, the C compiler is likely to optimise this for you.
"++" means "plus one"
eg
int x = 5;
x++; // the same as x = x + 1
cout << x; // will print 6
"+" is the known plus operator
++ is a convenience syntax. It does not really add capability to the language, but it adds a way of writing some common operations more concisely.
As a standalone statement a++; is identical to a+=1; is identical to a=a+1;
a++ can be useful in some situations that would otherwise need two statements:
while (a < N) doSomethingWith(a++);
is just a shorter form of
while (a<N)
{
doSomethingWith(a);
a=a+1;
}
I don't think there is anything you can write with an a++ that you couldn't also write with an a=a+1, but you can't just do a 1 for 1 substitution. Sometimes the 2nd form will require more code to be equivalent, since the 1st performs two things: produce the value of a, and then increment a. The a=a+1 form produces the value of a after the increment, so if you need the original value, you need a separate statement to process that first.
The difference between using the increment operator(ie. value++) vs using the addition operator(ie. value + 1) is that the first one sometimes can cause mutation especially if we are accessing a global variable inside a function;
Using increment operator.
// The global variable
var fixedValue = 4;
function incrementer () {
// Only change code below this line
return fixedValue ++;
// Only change code above this line
}
var newValue = incrementer(); // Should equal 5
console.log(fixedValue); // Should print 5
Using addition operator.
// The global variable
var fixedValue = 4;
function incrementer () {
// Only change code below this line
return fixedValue + 1;
// Only change code above this line
}
var newValue = incrementer(); // Should equal 5
console.log(fixedValue); // Should print 4
increment doing on register but addition do by ALU we can use + instead of increment but increment is faster

Find the most significant bit or log base 2 (floor) of a positive integer via straight line bit manipulation in C

This is what I need to do:
int lg(int v)
{
int r = 0;
while (v >>= 1) // unroll for more speed...
{
r++;
}
}
I found the above solution at: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
This works, butI need to do it without loops, control structures, or constants bigger than 0xFF (255), which has proven to be very hard for me to find. I've been trying to figure something out using conditionals in the form
( x ? y : z ) = (((~(!!x) + 1)) & y) | ((~(~(!!x) + 1)) & z)
but I can't get it to work. Thanks for your time.
Without any control structure, not even the ?: operator, you can simulate your own algo
int r = 0;
x >>= 1;
r += (x != 0);
x >>= 1;
r += (x != 0);
...
provided that, in C,
x is assumed to be positive (otherwise having int x=-1; for instance x >>= 1 n times is always != 0
a condition like x != 0 returns 0 (false) or 1 (*true)
That sounds like a homework. Well, if you can't use control structures, a good alternative is to precalculate what you can: divide and conquer. Solve for a smaller part (one byte, one nibble, your choice), and apply to the parts of your integer.

Operator Precedence - Expression Evaluation

For the following code snippet I get the output as 1. I want to know how it came?
void main()
{
int x=10,y=20,z=5,i;
i=x<y<z;
printf("%d",i);
}
i=x<y<z;, gets interpreted as i=(x<y)<z, which in turn gets interpreted as i=1<z, which evaluates to 1.
10 is less than 20, resulting in 1, and 1 is less than 5, resulting in 1. C doesn't chain relational operators as some other languages do.
It operates as follows:
Since < is a logical expression, x<y i.e 10<20 is true i.e 1. So it becomes 1<z i.e 1<5 which is again true i.e. 1 which is assigned to i. So i is 1.
This is because your code evaluates as:
void main()
{
int x=10,y=20,z=5,i;
i=((x<y)<z); //(x<y) = true = 1, (1 < 5) = true
printf("%d",i);
}
what output did you want?
In C,
i = 2 < 3; //i == 1.
i = 4 < 3; //i == 0.
If condition evaluates to false, value returned is 0, and 1 otherwise.
Also, x < y < z will be evaluated as ((x < y) < z).
x<y // 1 as (10 < 20) will return 1
result of(x<y)<z // 1 as (1<5) will return 1
C++ doesn't support multi-part comparisons like that.
x < y < z
is interpreted as
(x < y) < z
or that is, determine if x < y, then see if that boolean is less than z.
There's some discussion on why that is over at the software engineering StackExchange.
When you find yourself trying to do this, instead you need to write it as two separate comparisons joined by a boolean:
(x < y) && (y < z)

Resources