I'll be forthright about this: this one is for homework. However, as I've already completed the question and was just simply curious about different implementations of what I did, I thought it was okay to be consult y'all.
The question was to build a != function using bitwise operations. We are also allowed to use ! and +.
Returns 0 if x==y, otherwise it returns 1.
int eval_not_equal(int x, int y) {
int result = x ^ y;
if(result == 0) {
result = 0;
}
else {
result = 1;
}
return result;
}
I think this is a perfectly fine answer to the question, but I was wondering if it's possible to do this without using an if? There are quite a few different bitwise operations, and I'm sure there's gotta be a way to use them in order to replace the if that I used!
Would love to know what you guys think! :-)
I do not understand why you cannot use operator !=:
int eval_not_equal(int x, int y) {
return x != y;
}
but if that is some kind of challenge to avoid != in the code, then you can write like this:
int eval_not_equal(int x, int y) {
return !!(x ^ y);
}
In the code above, the result of x ^ y is treated as bool, then negated. The boolean equivalent of "false" is 0; "true" by default is 1 (but actually any non-zero integer is true)
If this is C++, or usage of stdbool is permitted (C99), then you can do also like this:
int eval_not_equal(int x, int y) {
return (bool) (x ^ y);
}
Update:
The question was to build a != function using only bitwise operations
If "only" is the key, then neither mine previous answers nor OP's solution are valid because ! is a boolean operator not bitwise. The same applies to type cast (bool) or if clause.
In my honest opinion, the following code is ridiculous, but it uses only bitwise operations:
int eval_not_equal(int x, int y) {
int xo = (x ^ y);
return (xo >> (ffs(xo) - 1)) & 1;
}
Function ffs() returns first set bit, i.e. the index of the first bit which equals to 1. We want only that bit, so we shift right the xor result by ffs - 1 to get rid of all lower bits, then do bitwise-and-with-1 to clear higher bits.
You could use double negation and a series of XOR's to accomplish this like this. This also works for negative numbers.
i32 is just a 32bit signed int
inline i32 negate(i32 x){ return ((x >> 31) | ((~x + 1) >> 31)) + 1; }
inline i32 ne(i32 a, i32 b){ return negate(a ^ b) ^ 1; }
int main(){
printf("result=%i\n", ne(-1, -1)); // 0
printf("result=%i\n", ne(-5, 0)); // 1
printf("result=%i\n", ne(0, 0)); // 0
printf("result=%i\n", ne(5, 5)); // 0
printf("result=%i\n", ne(1, 5)); // 1
printf("result=%i\n", ne(5, 1)); // 1
return 0;
}
You could just do the following:
return !(x ^ y);
Related
I'm a bit confused about the return type of a function, specifically when to return what. If we have any arbitrary function, let's say min(x,y), which should return according to the if statements, what should I return outside of their scope, which is required by the function's declaration. I've learned that it is common to use "return 0" or "return 1" but I don't understand why that is, and why it can't just return either of the if's return statements.
// compute difference largest - smallest
int diff(x, y)
{
if (x > y)
return x - y;
if (y > x)
return y - x;
if (x == y)
return 0;
return 1;
}
If X is bigger than Y, return X-Y (obvious)
If Y is bigger than X, return Y-X (also obvious)
If X and Y are equal, what do you think should be returned?If they're equal, both X-Y and Y-X are 0, so it doesn't really matter, does it?
Your final clause could be written any of:
return x-y;
return y-x;
return 0;
Because they two values are equal, they will ALL evaluate to 0.
The important part is to make sure the contract of the function is maintained.According to the comments, the function claims it will return the difference between the two values. So it should return the difference in all cases, whether the bigger value is X, Y, or they are equal.
The name of your function is extremely misleading. Because it is named min, it implies it will return the minimum value, not the difference. You should change the name of the function to something like diff or delta for clarity.
Ultimately, the simpler way to write the function would be:
// compute largest - smallest
int diff(int x, int y)
{
if (x > y)
return x - y; // Handles X is bigger than Y
else
return y - x; // Handles Y bigger than X, *or* X and Y are the same.
}
Finally, some very short versions that I would consider better.
int diff(int x, int y) { return x>y? x-y:y-x; }
int diff(int x, int y) { return abs(x-y); }
The compiler needs to make sure that you return something. If you have returns inside of if statements, such as you have, how is the compiler going to tell if you have covered all cases?
Even if you do something like the code below, how is the compiler going to know that you will return in all circumstances? Because of that this code will throw an error:
int min(int x, int y)
{
if (x > y)
return x - y;
if (y > x)
return y - x;
if (x==y)
return 1;
}
How can you combat this? You can write another return at the end of the function, as you have. Now the compiler know that you will return a value no matter what happens.
However there are better ways to make sure that you will always return a value. For example, you can use an else statement as a catch-all:
int min(int x, int y)
{
if (x > y)
return x - y;
if (y > x)
return y - x;
else
return 1;
}
Because the else is guaranteed to catch all cases, the compiler is happy about it, and will not throw any errors.
For a function that's computing the difference between two values, you would only return 1 if the difference between those two values was 1, 0 if they were equal.
There's a school of programming that says it's better to have a single return at the end of the function, rather than multiple returns scattered throughout. Instead of returning the difference in each branch, compute and store that difference, and return it at the end of the function:
int diff( int x, int y );
{
int delta = 0;
if ( x >= y )
delta = x - y;
else
delta = y - x;
return delta;
}
Like most programming rules, there are exceptions. There are times where you want to exit immediately if a certain condition isn't met. Knowing when which approach is the better one is a matter of experience.
The return type of the function is specified in the definition, int in your case.
Actually you need to specify the type of input arguments (x, y) and then the type of the output is usually derived from their type - like 2/3 cases in your function and the last one is integer (0).
Remark:
You also need to choose better name for the function.
This question already has answers here:
What is the most effective way for float and double comparison?
(34 answers)
Closed 6 years ago.
Please before you think that I'm asking the same N% Question read it first and please pay Attention to it.
I'm working on a project where I have more functions which returns double and it may be possible that some of them are the same which is a good thing in my project and if is true then I need a double comparison to see if are equal.
I know that doing an equality comparison if( x == y ) is not a smart thing and we don't need to speak why, but we can check for < or > which is the part of this Question.
Does the language (standard) guarantee this, that the comparison < and > are 100%?
If yes then, the following program can be used:
#include <stdio.h>
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || x > y){
/* Are not Equal */
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
}
Does foo(x, y); get executed? BecauseX and Y should be equal here.
EDIT:
This question doesn't seek a way to compare two double, it is only the fact that should I use, or should I don't use < > instead of ==
I know that doing an equality comparison if( x == y ) is not a smart thing
This is simply not true. It may be the right thing to do or the wrong thing to do, depending on the particular problem.
if (x < y || x > y)
This has guaranteed exactly the same effect1 as
if (x != y)
and the opposite effect of
if (x == y)
When one is wrong, the other is wrong too. When one is right, the other is right as well. Writing an equality condition with < and > symbols instead of == or != doesn't suddenly make it smarter.
[1] Except maybe when one of the operands is a NaN.
some of them are the same ... and if is true then I need a double comparison to see if are equal.
OP is questioning two different ways for testing FP equality and wondering if they are the functionally alike.
Aside from maybe NaN, which is not well defined by C, (but well defined by IEEE 754), both comparisons are alike yet fail conically equivalence testing.
Consider this double code:
if (a==b) {
double ai = 1.0/a;
double bi = 1.0/b;
printf("%d\n", ai == bi);
} else {
printf("%d\n", 1);
}
Is the result always "1"? Below is an exception (mouse over to see)
Consider a=0.0; b=-0.0. Both are equal to each other, but their inverses typically are not the same. One being positive infinity, the other: negative infinity.
The question comes down to how equal do you need? Are NaN important? Using memcmp(&a, &b, sizeof a) is certainly a strong test and maybe too strong for on select systems FP numbers can have the same non-zero value, yet different encodings. If these differences are important, or maybe just the exceptional case above, is for OP to decide.
For testing if 2 different codes/functions were producing the same binary64 result, consider rating their Unit-in-the-Last-Place difference. Something like the following: compare unsigned long long ULP_diff() against 0, 1 or 2. depending on your error tolerance.
// not highly portable
#include <assert.h>
unsigned long long ULP(double x) {
union {
double d;
unsigned long long ull;
} u;
assert(sizeof(double) == sizeof(unsigned long long));
u.d = x;
if (u.ull & 0x8000000000000000) {
u.ull ^= 0x8000000000000000;
return 0x8000000000000000 - u.ull;
}
return u.ull + 0x8000000000000000;
}
unsigned long long ULP_diff(double x, double y) {
unsigned long ullx = ULP(x);
unsigned long ully = ULP(y);
if (x > y) return ullx - ully;
return ully - ullx;
}
If you want fractional number equality, you either have to use an epsilon comparison (ie. check if the numbers are close enough to one another within a specific threshold), or use some fixed-point arithmetic very carefully to avoid rounding errors.
And yes, this same question has been asked more times than necessary:
Most effective way for float and double comparison
Floating point equality and tolerances
You need to do more reading into how comparisons work, and specifically why floating point equality doesn't work. It's not an issue with the equals operator itself, as you appear to think (For arithmetic types [when no special values like NaN are involved], !(x > y || y > x) will always be the same as x == y. In fact, most compilers will optimize x < y || x > y to x != y), but rather because rounding error is a basic part of floating point operation in the first place. x == y does indeed work for floating point types, and you can do it freely. It becomes an issue after you do any arithmetic operation and then want to compare them, because it's unpredictable what the rounding error will do.
So essentially, yes. Compare equality all you want unless you are actually doing anything with the doubles. If you are just using them as an index or something of the like, there shouldn't be a problem, as long as you know you are assigning them the same value. Using boolean identities won't save you from the basic functionality of floating-point numbers.
First of all your conditional is a little off. To check for non equality you want
( x < y || y < x)
not
(x < y || y > x )
which just checks the same thing twice, meaning x < y comes back as false.
Ignoring that small issue:
Yes > and < should be 100% in that it is almost always the same as the ==. The only difference is different behavior with Nan. But it doesn't fix your problem.
Here is a really contrived example.
#include <stdio.h>
void foo(double x, double y){
printf( "OK a:%f, b:%f\n",x,y);
}
void bar(double x, double y){
printf( "BAD a:%f, b:%f\n",x,y);
}
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || y < x){
/* Are not Equal */
bar(x, y);
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
for( int i = 0; i < 1000; i++) {
y = y + 0.1;
}
x = x + 100;
if( x < y || y < x){
bar(x, y);
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
}
Here is you output (hint its BAD)
$ ./a.exe
OK a:3.140000, b:3.140000
BAD a:103.140000, b:103.140000
Best practice I know for double equality is to check there closeness within some epsilon,
eps = 0.00000000001
if( abs( x - y ) < eps ) {
printf("EQUAL!");
}
#include <stdio.h>
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || x > y){
/* Are not Equal */
}else{
/* Are Equal, foo() will be called here\n" */
printf("yes");
}
}
prints yes
I got the following question in an interview: "Write a C function that round up a number to next power of 2."
I wrote the following answer:
#include <stdio.h>
int next_pwr_of_2(int num)
{
int tmp;
do
{
num++;
tmp=num-1;
}
while (tmp & num != 0);
return num;
}
void main()
{
int num=9;
int next_pwr;
next_pwr=next_pwr_of_2(num);
printf(" %d \n",next_pwr);
}
The question is: why does the program go out of its do-while loop when getting to the values 11 and 10?
Precedence my friend, precedence.
while ((tmp & num) != 0);
Will fix it. ( note the parenthesis around the expression tmp & num)
!= has higher precedence than &, so num != 0 is evaluated before tmp & num.
If you skip the parenthesis, the expression that is evaluated is : tmp & (num != 0)
First time round, tmp = 9 (1001) and num != 0 is 1 (0001) so & evaluates to 1 (true), and the loop continues.
Now at the end of second iteration, we have, tmp = 10 (1010). num != 0 is again 0001, so 1010 & 0001 evaluates to 0, hence the loop breaks.
Here is the table for reference.
The precedence order is quite unusual, as noted here. Happens all the time :).
Of course you don't have to remember any precedence order, which is just to help the compiler in deciding what is done first if the programmer does not make it clear. You can just correctly parenthesize the expression and avoid such situations.
The loop exits because you did not put parentheses around your condition. This should teach you not to put the unnecessary != 0 in your C/C++ conditions.
You can simplify your code quite a bit, though.
First, observe that temp equals the prior value of num, so you can change your loop to
int tmp;
do {
tmp = mum++;
} while (tmp & num); // Don't put unnecessary "!= 0"
Second, the interviewer was probably looking to see if you are familiar with this little trick:
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
Unlike your code that may take up to 1,000,000,000 operations to complete, the above always completes after twelve operations (a decrement, an increment, five shifts, and five ORs).
Such questions always deserve counter questions to clarify requirements, if only to demonstrate your thinking and analytical skills and even creativity - that is what the interview should be about.
For example in the absence of any specification that the "number" in question is necessarily an integer, you might propose the following:
int nextPow2( double x )
{
return (int)pow( 2, ceil(log10(x) / log10(2))) ;
}
But if you did you might also express concern about the applicability of such a solution to an embedded system with possibly no floating-point unit.
I would answer by saying no one should write that in pure C. Especially in an embedded environment. If the chipset does not provide a feature to count the number of leading zeros in a word, then it's probably pretty old, and certainly not something you want to be using. If it does, you would want to use that feature.
As an example of a non-standard way to round an unsigned integer up to a power of two (you really need to clarify the type of the argument, as "number" is ambiguous) using gcc, you could do:
unsigned
round_up( unsigned x )
{
if( x < 2 ) {
return 1U;
} else {
return 1U << ( CHAR_BIT * sizeof x - __builtin_clz( x - 1 ));
}
}
In contrast to what others have said, the bit-twiddling trick actually can be used on any number of bits portably. Just change it a bit:
unsigned int shift = 1;
for (v--; shift < 8 * sizeof v; shift <<= 1)
{
v |= v >> shift;
}
return ++v;
I believe any compiler will optimize the loop away, so it should be the same performence-wise (plus I think it looks better).
Yet another variant.
int rndup (int num)
{
int tmp=1;
while (tmp<num)
{
tmp*=2;
}
return tmp;
}
Another variant using while loop and bit-wise operator
int next_pwr_of_2(unsigned &num)
{
unsigned int number = 1;
while (number < num)
{
number<<=1;
}
return number;
};
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.
Using only bitwise operators (|, &, ~, ^, >>, <<) and other basic operators like +, -, and !, is it possible to replace the "==" below?
int equal(int x, int y) {
return x == y;
}
Remember that an XOR is the exactly same as NOT EQUALS and XNOR is exactly the same as EQUALS. So, the following will give you exactly what you want:
return !(x ^ y);
Two numbers are equal if there is no difference between them:
int equal(int x, int y){
return !(x-y);
}
The C ! operator is really just shorthand for != 0, so using it seems very close to cheating :)
Here's my take just using bitwise operations, assuming a 32-bit two's complement machine with arithmetic right shifts (technically, in C arithmetic right shifts are undefined, but every C compiler I've ever seen on a two's complement machine supports this correctly):
int t = (x - y) | (y - x); // <0 iff x != y, 0 otherwise
t >>= 31; // -1 iff x != y, 0 otherwise
return 1 + t; // 0 iff x != y, 1 otherwise
That said, actual compilers don't have this problem. Real hardware actually has direct support for comparisons. The details depend on the architecture, but there's two basic models:
Condition codes returned for arithmetic operations (e.g. x86 and ARM do this). In this case, there's usually a "compare" instruction which subtracts two values, doesn't write back to an integer register but sets the condition code/flags based on the result.
More RISC-like platforms typically have direct "branch if equal" and "branch if less than" operands that do a comparison and branch based on the result. It's basically equivalent to the C code
if (a == b) goto label;
or
if (a < b) goto label;
all in one machine instruction.
This example is the same as subtraction, but is more explicit as to how some architectures do register comparison (like the ARM, I believe).
return !(1 + ~x + y);
The 1 signifies the carry-bit input into the ALU. One number x is bitwise complemented. Taking the complement and adding 1 produces the two's complement of the number (x becomes -x), and then it's added to the other number to get the difference to determine equality.
So if both numbers are equal, you get -x + x => 0.
(On a register level the ! operator isn't done, and you just test the "zero bit" of the condition codes or flags register, which gets set if the register operation produces a result of zero, and is clear otherwise.)
As XOR is same as (!=), hence (x ^ y) will return 0 only for equal values.
My take is the following because it is sensible, uses bit-wise operator and working.
int notEqual(int x, int y){
return (x ^ y);
}
My Take on this
int equal(int x, int y){
if((x & ~y) == 0)
return 1;
else
return 0;
}
Explanation: If x == y, then x & ~y evaluates to 0 return 1, else return 0 as x!=y.
Edit1: The above is equivalent to
int equal(int x, int y){
return !(x & ~y) ; // returns 1 if equal , 0 otherwise.
}
The above code fails in certain cases where the Most significant bit turns to 1. The solution is to add a 1. i.e correct answer is
return !(x & (~y +1) );