For this assignment I can only use basic bitwise operators and no control structures, so I've come up with this code so far to convert sign-magnitude to two's complement.
int sm2tc(int x) {
// Invert and add 1
// Problem: sm has 2 zeros.. 1000...000 & 0000...000
int tmin = 1 << 31;
int mask = x >> 31; // Determine sign of x
int mask2 = ~tmin; // Negate tmin to get 0111111...
int first = (x ^ mask) + (~mask + 1) ;
int second = first & mask2; // Turns of MSB
return second;
}
Where have I gone wrong?
So, what you really want to compute is
result = (x & sign_bit) ? -(x & ~sign_bit) : x;
But of course you're not allowed control structures. The first step is to rewrite -(x & ~sign_bit) using just the + and ^ operators: (-1 ^ (x & ~sign_bit)) - -1. Now note that if (x & sign_bit) is zero then (0 ^ (x & ~sign_bit)) - 0 is equal to x. We now have
result = (x & sign_bit) ? (-1 ^ (x & ~sign_bit)) - -1 : (0 ^ (x & ~sign_bit)) - 0
You then just need to replace the -1 and 0 with functions of x that generate those values depending on the sign bit, and lo and behold both sides of the condition become the same expression and the condition becomes unnecessary.
Related
Me and my group of 4 people are both completely blanking on how to correctly do an arithmetic left shift of an int x, by an amount of n bits.
It is a for a homework problem on bit manipulation for C. We are not allowed to use loops, if statements, or any operations over 15. I've attached the code given below. Also, the simple solution x << n does not work, even though I'm sure we are missing something obvious. If anyone could help or provide guidance, it would be much appreciated.
/*
* arithLeftShift - Do an arithmetic left shift of x by n bits.
* Can assume that 0 <= n <= 31
* Examples: arithLeftShift(0x87654321,4) = 0xF6543218
* Legal ops: ~ & ^ | + << >> !
* Max ops: 15
* Rating: 3
*/
int arithLeftShift(int x, int n) {
return 0;
}
Current error message:
Test arithLeftShift(-2147483648[0x80000000],1[0x1]) failed...
...Gives 0[0x0]. Should be -2147483648[0x80000000
Actually, It is not arithmetic left shift.It's your arithLeftShift with your sign bit needn't a left shift. And the high bits needed to be shifted to the low position, It looks like a cycle shift.
#include<stdio.h>
int main()
{
arithLeftShift(0x87654321,4);
}
int arithLeftShift(int x,int n)
{
int temp,i; //define two auto variables,
i=x>>(32-n);//i for x's high n bits.
temp=x<<n;//temp for x left shift n bits
if(x>0)//sign bit is 0,
{
x=temp+i;
x=x>0?x:x^0x80000000;//change the x sign bit is 0;
}
else
{//when you do right shift, there will be different with different compliers and your x.
if(i>0){//This means when you do right shift, 0 be inserted into high bits.
x=temp+i;
}
else
{
i=(0x80000000>>(32-n));
x=temp+i;
}
x=x>0?~(x^(~0x80000000)):x;//change the x sign bit is 1
printf("%x\n",x);
}
}
Your ask seems to be to "Rotate" the integer "Left", "n" number of times but retain the "Sign Bit"(MSB) if set.
One solution would be......
#include <stdio.h>
#define INT_BITS 32
int arithLeftShift(int x, int n) {
int res;
res = (x << n | (x >> (INT_BITS - n) & ~(~0 << n))) | x & (~0 << (INT_BITS - 1));
return res;
}
int main(){
int x = 0x87654321;
int n = 4;
printf("0x%x\n",arithLeftShift(x,n));
}
Explanation:
(x << n)
Left shift x, n times - the last n bits are zero.
(x >> (INT_BITS - n) & ~(~0 << n))
Right shift x (INT_BITS - n) times to put the first n bits at the correct position and "AND" it with ~(~0 << n) to set the upper bits to zero.This will take care of "sign extension", if any.
(x << n | (x >> (INT_BITS - n) & ~(~0 << n)))
"OR" them to perform the "Rotate Left" operation.
x & (~0 << (INT_BITS - 1)
Left shift "-1", 31 times and "AND" it with x to check if the MSB of x is set.
(x << n | (x >> (INT_BITS - n) & ~(~0 << n))) | x & (~0 << (INT_BITS - 1))
Finally "OR" the above expressions to get your answer.
For unsigned int x, is it possible to calculate x % 255 (or 2^n - 1 in general) using only the following operators (plus no loop, branch or function call)?
!, ~, &, ^, |, +, <<, >>.
Yes, it's possible. For 255, it can be done as follows:
unsigned int x = 4023156861;
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
// At this point, x will be in the range: 0 <= x < 256.
// If the answer 0, x could potentially be 255 which is not fully reduced.
// Here's an ugly way of implementing: if (x == 255) x -= 255;
// (See comments for a simpler version by Paul R.)
unsigned int t = (x + 1) >> 8;
t = !t + 0xffffffff;
t &= 255;
x += ~t + 1;
// x = 186
This will work if unsigned int is a 32-bit integer.
EDIT: The pattern should be obvious enough to see how this can be generalized to 2^n - 1. You just have to figure out how many iterations are needed. For n = 8 and a 32-bit integer, 4 iterations should be enough.
EDIT 2:
Here's a slightly more optimized version combined with Paul R.'s conditional subtract code:
unsigned int x = 4023156861;
x = (x & 65535) + (x >> 16); // Reduce to 17 bits
x = (x & 255) + (x >> 8); // Reduce to 9 bits
x = (x & 255) + (x >> 8); // Reduce to 8 bits
x = (x + ((x + 1) >> 8)) & 255; // Reduce to < 255
Just create an array with all the values (only either need 32 or 64 entries (i.e. 128 or 512 bytes). Then just do a look up.
Sure. Just get out one of your old computer architecture textbooks and refresh your memory on boolean algebra. A CPU's ALU does it with ANDs and ORs; you can, too.
But why?
An academic exercise? Homework? Curiousity?
Using only:
<< >> | ^ & +
How can I make a function that is equivalent to the logical not operator (!)?
Right now I have:
int i = (~x + 1) >> 31;
int j = (x + 1) >> 31;
i = i | j;
i = i & 1;
return i ^ 1;
It works for everything, but -1.
I will assume that you are working with ints that are 32-bit, signed, and use 2's complement notation. The unique thing about the number 0 is that neither 0 nor its negation have a 1 for the sign bits. This code would work if you were allowed to use the negation operator (-):
int not(int x)
{
return (-x | x) >> 31 & 1 ^ 1;
}
You can't use minus, but that is ok because for all x we know that -x is equal to ~x + 1 which is equal to (x ^ -1) + 1. That's how 2's complement notation works. So the final answer is:
int not(int x)
{
return ( (x^-1)+1 | x ) >> 31 & 1 ^ 1;
}
EDIT 1:
Ok, here is the "ANSI" version of the function that makes no assumption about the size of the int and does not rely on the undefined behavior of right-shifting a signed int. It works for me in MinGW:
int not(int x)
{
unsigned int y = x;
return (( ((y^-1)+1) | y ) >> (sizeof(x)*8-1)) ^ 1;
}
Assuming that x is a 32-bit unsigned value:
x = x | (x >> 1)
x = x | (x >> 2)
x = x | (x >> 4)
x = x | (x >> 8)
x = x | (x >> 16)
At this point, if x was 0 then it's still 0. If it had a non-zero value, it now has the bit pattern 111....111.
With a two-complement representation, you can now simply add 1 and get the desired result:
x = x + 1
This solution assumes quite a bit about integer representation, types, etc.
(The "code" above is not valid C code, of course).
Kind of 'cheating', but:
bool logicalNot(int i)
{
return((bool)i ^ true);
}
I'm assuming there's nothing in the rules about composition of functions/typecasting/implicit type conversions?
Check whether a number x is nonzero using the legal operators except !.
Examples: isNonZero(3) = 1, isNonZero(0) = 0
Legal ops: ~ & ^ | + << >>
Note : Only bitwise operators should be used. if, else, for, etc. cannot be used.
Edit1 : No. of operators should not exceed 10.
Edit2 : Consider size of int to be 4 bytes.
int isNonZero(int x) {
return ???;
}
Using ! this would be trivial , but how do we do it without using ! ?
The logarithmic version of the adamk function:
int isNotZero(unsigned int n){
n |= n >> 16;
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n & 1;
};
And the fastest one, but in assembly:
xor eax, eax
sub eax, n // carry would be set if the number was not 0
xor eax, eax
adc eax, 0 // eax was 0, and if we had carry, it will became 1
Something similar to assembly version can be written in C, you just have to play with the sign bit and with some differences.
EDIT: here is the fastest version I can think of in C:
1) for negative numbers: if the sign bit is set, the number is not 0.
2) for positive: 0 - n will be negaive, and can be checked as in case 1. I don't see the - in the list of the legal operations, so we'll use ~n + 1 instead.
What we get:
int isNotZero(unsigned int n){ // unsigned is safer for bit operations
return ((n | (~n + 1)) >> 31) & 1;
}
int isNonZero(unsigned x) {
return ~( ~x & ( x + ~0 ) ) >> 31;
}
Assuming int is 32 bits (/* EDIT: this part no longer applies as I changed the parameter type to unsigned */ and that signed shifts behave exactly like unsigned ones).
Why make things complicated ?
int isNonZero(int x) {
return x;
}
It works because the C convention is that every non zero value means true, as isNonZero return an int that's legal.
Some people argued, the isNonZero() function should return 1 for input 3 as showed in the example.
If you are using C++ it's still as easy as before:
int isNonZero(int x) {
return (bool)x;
}
Now the function return 1 if you provide 3.
OK, it does not work with C that miss a proper boolean type.
Now, if you suppose ints are 32 bits and + is allowed:
int isNonZero(int x) {
return ((x|(x+0x7FFFFFFF))>>31)&1;
}
On some architectures you may even avoid the final &1, just by casting x to unsigned (which has a null runtime cost), but that is Undefined Behavior, hence implementation dependant (depends if the target architecture uses signed or logical shift right).
int isNonZero(int x) {
return ((unsigned)(x|(x+0x7FFFFFFF)))>>31;
}
int is_32bit_zero( int x ) {
return 1 ^ (unsigned) ( x + ~0 & ~x ) >> 31;
}
Subtract 1. (~0 generates minus one on a two's complement machine. This is an assumption.)
Select only flipped bit that flipped to one.
Most significant bit only flips as a result of subtracting one if x is zero.
Move most-significant bit to least-significant bit.
I count six operators. I could use 0xFFFFFFFF for five. The cast to unsigned doesn't count on a two's complement machine ;v) .
http://ideone.com/Omobw
Bitwise OR all bits in the number:
int isByteNonZero(int x) {
return ((x >> 7) & 1) |
((x >> 6) & 1) |
((x >> 5) & 1) |
((x >> 4) & 1) |
((x >> 3) & 1) |
((x >> 2) & 1) |
((x >> 1) & 1) |
((x >> 0) & 1);
}
int isNonZero(int x) {
return isByteNonZero( x >> 24 & 0xff ) |
isByteNonZero( x >> 16 & 0xff ) |
isByteNonZero( x >> 8 & 0xff ) |
isByteNonZero( x & 0xff );
}
basically you need to or the bits. For instance, if you know your number is 8 bits wide:
int isNonZero(uint8_t x)
{
int res = 0;
res |= (x >> 0) & 1;
res |= (x >> 1) & 1;
res |= (x >> 2) & 1;
res |= (x >> 3) & 1;
res |= (x >> 4) & 1;
res |= (x >> 5) & 1;
res |= (x >> 6) & 1;
res |= (x >> 7) & 1;
return res;
}
My solution is the following,
int isNonZero(int n)
{
return ~(n == 0) + 2;
}
My solution in C. No comparison operator. Doesn't work with 0x80000000.
#include <stdio.h>
int is_non_zero(int n) {
n &= 0x7FFFFFFF;
n *= 1;
return n;
}
int main(void) {
printf("%d\n", is_non_zero(0));
printf("%d\n", is_non_zero(1));
printf("%d\n", is_non_zero(-1));
return 0;
}
My solution,though not quite related to your question
int isSign(int x)
{
//return 1 if positive,0 if zero,-1 if negative
return (x > 0) - ((x & 0x80000000)==0x80000000)
}
if(x)
printf("non zero")
else
printf("zero")
The following function example should work for you.
bool isNonZero(int x)
{
return (x | 0);
}
This function will return x if it is non-zero, otherwise it will return 0.
int isNonZero(int x)
{
return (x);
}
int isNonZero(int x)
{
if ( x & 0xffffffff)
return 1;
else
return 0;
}
Let assume Int is 4 byte.
It will return 1 if value is non zero
if value is zero then it will return 0.
return ((val & 0xFFFFFFFF) == 0 ? 0:1);
isPositive - return true if x > 0, otherwise false
Example: isPositive(-1)
Legal ops: ! ~ & ^ | + << >>
Max ops: 8
Note: No conditional statements are allowed.
inline bool isPositive(int32_t x) {
return ???;
}
int isPositive(int x) {
return !((x&(1<<31)) | !x);
}
x&(1<<31 is to check if the number is negative.
!x is to check if the number is zero.
A number is positive if it's not negative and not zero.
return !((x & 0x80000000) >> 31 | !x);
int isPositive(int x)
{
return (!(x & 0x80000000) & !!x);
}
Let's play with the sign bit: sign(~n) : 1 if n >= 0
To get rid of the case when n is 0: sign(~n + 1) : 1 if n > 0 or n = MIN_INT
So, we want the case when both functions return 1:
return ((~n & (~n + 1)) >> 31) & 1;
Why not use XOR (^)?
Try this,
{
return ((x>>31)&1)^(!!x);
}
It can deal with the 0 case well.
Assuming a two’s complement representation (not always the case!), this can be achieved by testing whether the most significant bit is set (in which case the number is negative).
Notice that the following code uses illegal operations (+, * and -) but these are for clarity and platform independence only. If you know more about your particular platform, e.g. that int is a 32 bit number, the relevant constants can be replaced by their numeric value.
// Will be 1 iff x < 0.
int is_neg = (x & (INT_MAX + 1)) >> (CHAR_BIT * sizeof(int) - 1);
// Will be 1 iff x != 0.
int is_not_zero = !!x;
return !is_neg & is_not_zero;
Haven't done assembler for quite a while, but as far as I remember first digit in the word represents negative value e.g. 1000 is -8, hence if most significant bit is 1 the number is negative. So the answer is !(x>>31)
if your working with a number system that uses the MSB as the signage bit, you can do:
int IsPositive(int x)
{
return (((x >> 31) & 1) ^ 1) ^ !x;
}
You have another option here:
int is_positive = (0&x^((0^x)&-(0<x)));
It is just a (0 & min(0,x)).
Test here
int isPositive(int x)
{
return ( ! (x & ( 1 << 31 ) ) );
}
It will return 1 if given no is +ve and return 0 if given no is -ve
in this function we got sign bit if that is 1 it means no is -ve so we return 0
and if sign bit is 0 it means number is +ve so we return 1 .
int x,len;
x = 0x0fffffff;
len = (sizeof(x) * 8) - 2;
if ((x>>len))
printf("Negative\n");
else
printf("Positive\n");
X will be either int or char(Integral type).
return !((x >> 31) & 1);
This is to check MSB.