简体   繁体   English

仅使用“〜&^ |实现逻辑右移 + << >> =“运营商和20个运营

[英]Implementing logical right shift using only “~ & ^ | + << >> =” operators and 20 operations

So I have an assignment that I have to code a function in c that uses only the bitwise operations of ~ , & , ^ , | 所以我有一个赋值,我必须在c中编写一个函数,它只使用〜,&,^,|的按位运算 , + , << , >> , and =. ,+,<<,>>和=。 I have to use only 20 operations. 我只需要使用20次操作。 And I am not allowed to use control structures such as, if-else , for, while, switch, or anything else that excutes code in conditional blocks. 并且我不允许使用控制结构,例如if-else,for,while,switch,或其他任何可以在条件块中使用代码的东西。 Also type casting is also out and the bytes that are not declared in the function header (which is given to me), are limited to 1 byte or 8 bit values; 同样类型转换也是输出 ,并且未在函数头中声明的字节(给我),限制为1个字节或8位值; so I have hex 0 through FF. 所以我有十六进制到FF。

The function I have to code is a logical right shift. 我必须编写的函数是逻辑右移。 So instead of the bits filling up with the sign bit they should fill up with 0's 因此,不是填充符号位的位,而是填充0

This is what I have done: 这就是我所做的:

int logicalShift(int x, int n) {
    int op=0xFFFFFFFF;
    int tcn=(~n+1);
    int sizeshift=0x20 & tcn;
    op=(op<<sizeshift);
    return ((x>>n) + (op));
}

This is what I expect to get ( for an x=0x80000000, and n=0x01) I expect to get 0x40000000 which is 1073741824 in decimal. 这是我期望获得的(对于x = 0x80000000,并且n = 0x01)我期望得到0x40000000,其为十进制的1073741824。 This is what I get. 这就是我得到的。 However (for an x=0x80000000, and n=0x0 I expect to get 0x80000000, however I get 0x7fffffff which is my answer minus a bit. I could add a bit, but it messes up the first answer. So What am I doing wrong that I have one case but not the other. I have also tried. 然而(对于x = 0x80000000,n = 0x0我期望得到0x80000000,但是我得到0x7fffffff这是我的答案减去一点。我可以添加一点,但它弄乱了第一个答案。所以我做错了什么我有一个案子而不是另一个案子。我也试过了。

int logicalShift(int x, int n) {
    int op=0xFFFFFFFF;
    int tcn=(~n+1);
    int sizeshift=0x20 & tcn;
    op=(op<<sizeshift);
    return ((x>>n) + (op  ^ ~n));
}

I thought that if I XOR the set of bits zeroing out the sign bits with all 1's for the 0 case I would end up with something that was not negative (aka) 0x7fffffff when it went through the compilers conversion to 2's complement. 我认为,如果我对0位的所有1的符号位进行异或运算,那么当它通过编译器转换为2的补码时,我会得到一些非负的(也就是)0x7fffffff。 It ended up making it worse. 它最终使情况变得更糟。 Please set me in the right direction what should I consider and why? 请让我指出正确的方向我应该考虑什么?为什么?

The difference between logical and arithmetic shift are the bits shifted in from the left. 逻辑移位和算术移位之间的差异是从左侧移入的位。 To implement logical shift in terms of arithmetic you can do the arithmetic shift and then clear the new bits. 要在算术方面实现逻辑移位,您可以执行算术移位,然后清除新位。 In pseudo-code: 在伪代码中:

  1. Generate a mask that will clear the leftmost n bits when ANDed with the result. 生成一个掩码 ,当与结果进行AND运算时,该掩码将清除最左边的n位。
  2. Shift right by n bits. 向右移动n位。
  3. AND the mask. 和面具。

Using AND means you don't have to care what bits are shifted in. You just want to unconditionally set them to 0. 使用AND意味着您不必关心哪些位被移入。您只需要无条件地将它们设置为0。

The question then is how to generate the mask. 那么问题是如何生成掩码。 I'll leave that as an exercise for you. 我会把它作为锻炼给你。

If the sign bit is not set, (x >> n) == (x >>> n) . 如果未设置符号位,则(x >> n) == (x >>> n) If the sign bit is set, we mask it off before doing the shift, then add it back: (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1)) 如果符号位置位,我们在执行移位之前将其屏蔽掉,然后将其添加回: (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1)) (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1)) . (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1))

If we know, which of the two cases we have, the computation becomes easier. 如果我们知道,我们拥有的两种情况中的哪一种,计算就变得更容易了。 If we could use if , we could combine the two cases. 如果我们可以使用if ,我们可以将这两种情况结合起来。 We have to emulate a conditional. 我们必须模仿有条件的。

int signBit1 = (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1));
int signBit0 = x >> n;
var signBitIsolated = x & 0x80000000; // either 0 or 0x80000000
var signMask = signBitIsolated >> 31; //either 0 or 0xFFFFFFFF
var combined = (signBit0 & ~signMask) | (signBit1 & signMask);
return combined;

We simulate a conditional by generating an all-zeros or all-ones mask, and or-ing the two cases. 我们通过生成全零或全1掩码以及两种情况来模拟条件。

I think you said that the input domain is restricted to one byte. 我想你说输入域只限于一个字节。 The same idea applies, but with different constants. 同样的想法适用,但具有不同的常数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM