C 中任意整数的位循环

发布于 2024-09-27 16:35:01 字数 870 浏览 5 评论 0原文

将整数 2 传递给此函数,然后返回整数 4

x = 2;
x = rotateInt('L', x, 1); 

(将位左移 1)

示例: 00000010->向左旋转 1 -> 00000100

但如果我通过这个:

x = rotateInt('R', x, 3); 

它将返回 64, 01000000

这是代码,有人可以纠正错误...谢谢

int rotateInt(char direction, unsigned int x, int y)
{
    unsigned int mask = 0;
    int num = 0, result = 0;
    int i;

    for (i = 0; i < y; i++)
    {     
        if (direction == 'R')
        {
            if ((x & 1) == 1)     
                x = (x ^ 129);
            else    
                x = x >> 1;
        }
        else if (direction == 'L')
        {
            if ((x & 128) == 1)  
                x = (x ^ 129);   
            else
                x = x << 1;
        }
    }
result = (result ^ x);
return result;   
}

Pass a integer 2 to this function and then return a integer which is 4

x = 2;
x = rotateInt('L', x, 1); 

(left shift the bits by 1)

Example:
00000010 -> rotate left by 1 -> 00000100

but if I pass this:

x = rotateInt('R', x, 3); 

it will return 64, 01000000

Here is the code, can someone correct the error... thanks

int rotateInt(char direction, unsigned int x, int y)
{
    unsigned int mask = 0;
    int num = 0, result = 0;
    int i;

    for (i = 0; i < y; i++)
    {     
        if (direction == 'R')
        {
            if ((x & 1) == 1)     
                x = (x ^ 129);
            else    
                x = x >> 1;
        }
        else if (direction == 'L')
        {
            if ((x & 128) == 1)  
                x = (x ^ 129);   
            else
                x = x << 1;
        }
    }
result = (result ^ x);
return result;   
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

银河中√捞星星 2024-10-04 16:35:01

所以,我假设您知道什么是右移和左移。并且您知道算术移位和逻辑移位之间的区别。

C 只有算术移位。它不进行逻辑移位,也不进行旋转。好吧,我撒谎了,C 对无符号整数进行逻辑移位。

旋转确实是这样的:它与逻辑移位相同,只不过当您移位超过数字末尾时,数字“环绕”到另一侧。例如,

0010 右旋转为 0001。如果再次右旋转,您将得到1000。看,1 环绕或旋转到整数的另一侧。

左旋转类似:0100左旋转1000左旋转0001左旋转0010等。

请注意,旋转不不像算术右移那样保留符号位。

所以,C 语言只有算术移位。所以你必须手动实现“旋转”部分。所以,向左旋转。您可能想要:

  1. 捕获最左边位的值。 (是 0 还是 1?)
  2. 进行左移
  3. 根据我们捕获的内容,将最右边的位 - 这是我们在步骤 1 中讨论的位(需要旋转)设置为正确的值步骤 1.

您应该能够找出类似的右旋转方法。

祝你好运!

So, I'll assume you know what right and left shifts are. And that you know the difference between arithmetic and logical shifts.

C only has arithmetic shifts. It doesn't do logical shifts, nor does it do rotates. okay I lied, C does logical shifts on unsigned ints.

A rotate does, well, exactly that: it's the same as a logical shift, except when you shift past the end of the number, the digits "wrap around" to the other side. For example

0010 right-rotated is 0001. If you right-rotate again, you get 1000. See, the 1 wrapped around, or rotated, to the other side of the integer.

The left rotate is similar: 0100 left rotate 1000 left rotate 0001 left rotate 0010 etc.

Note that rotates don't keep the sign bit as an arithmetic right-shift would.

So, C only has arithmetic shifts. So you have to implement the "rotate" part manually. So, take a left-rotate. You would want to:

  1. Capture the value of the left-most bit. (is it a 0 or 1?)
  2. Do a left-shift
  3. Set the right-most bit - which is the bit we talked about in step 1 (which needs to be rotated around) to the correct value, based on what we captured from step 1.

You should be able to figure out a similar method for right rotates.

good luck!

断爱 2024-10-04 16:35:01

接受的答案非常好而且直接。

然而,我正在做一些 K&R 练习来刷新我的 C,并想分享这个向右旋转的函数,这对于尝试学习按位运算的人来说可能会派上用场。

unsigned int rightRotateBits(unsigned int inputWord, int numberOfBitsToRotate) {
    int bitWidth = sizeof(inputWord) * 8;
    // Rotating 32 bits on a 32-bit integer is the same as rotating 0 bits;
    //   33 bits -> 1 bit; etc.
    numberOfBitsToRotate = numberOfBitsToRotate % bitWidth;

    unsigned int tempWord = inputWord;

    // Rotate input to the right
    inputWord = inputWord >> numberOfBitsToRotate;

    // Build mask for carried over bits
    tempWord = tempWord << (bitWidth - numberOfBitsToRotate);

    return inputWord | tempWord;
}

对于左旋转,只需将 -1 到 -31 之间的值传递给 bitAmount 参数即可。

请注意,此功能更注重可教性/易读性/简单性,而不是效率/可移植性/紧凑性。

The accepted answer is very nice and straight-forward.

However, I was doing some K&R exercises to refresh my C, and wanted to share this rotate-to-the-right function which may come in handy for people trying to learn bit-wise operations.

unsigned int rightRotateBits(unsigned int inputWord, int numberOfBitsToRotate) {
    int bitWidth = sizeof(inputWord) * 8;
    // Rotating 32 bits on a 32-bit integer is the same as rotating 0 bits;
    //   33 bits -> 1 bit; etc.
    numberOfBitsToRotate = numberOfBitsToRotate % bitWidth;

    unsigned int tempWord = inputWord;

    // Rotate input to the right
    inputWord = inputWord >> numberOfBitsToRotate;

    // Build mask for carried over bits
    tempWord = tempWord << (bitWidth - numberOfBitsToRotate);

    return inputWord | tempWord;
}

For left-rotations just pass values between -1 and -31 to the bitAmount argument.

Do note that this function favors teachability/legibility/simplicity over efficiency/portability/compactness.

回忆追雨的时光 2024-10-04 16:35:01

由于没有人告诉您如何实现这一点,您可以使用内在函数,对于 Visual Studio,它们是 _rotl、_rotl64、_rotr、_rotr64。

哦,但是旋转和移位是两个不同的东西!

Since no one told you how to implement this, you can use intrinsics, for visual studio they are _rotl, _rotl64, _rotr, _rotr64.

Oh, but rotation and shifts are 2 different things!

冧九 2024-10-04 16:35:01

我也在阅读 K&R,所以这是一个非常简单的无符号整数旋转函数:

unsigned int rightrot(unsigned int x, unsigned int n)
{
  return (x >> n) | (x << (sizeof(int) * CHAR_BIT - n)); /* CHAR_BIT is defined in limits.h */
}

unsigned int leftrot(unsigned int x, unsigned int n)
{
  return (x << n) | (x >> (sizeof(int) * CHAR_BIT - n));
}

其中 n 是要旋转的位数。

I was reading K&R, too, so this is a very straightforward rotate function for unsigned int:

unsigned int rightrot(unsigned int x, unsigned int n)
{
  return (x >> n) | (x << (sizeof(int) * CHAR_BIT - n)); /* CHAR_BIT is defined in limits.h */
}

unsigned int leftrot(unsigned int x, unsigned int n)
{
  return (x << n) | (x >> (sizeof(int) * CHAR_BIT - n));
}

Where n is the number of bits to rotate.

跨年 2024-10-04 16:35:01

看来你向右旋转是正确的。 1从侧面摔倒,又从左边折回来?

不管怎样,这里是你的成分:

http://tigcc.ticalc.org/doc/keywords。 html#if - 用于确定它是“L”还是“R”

http ://tigcc.ticalc.org/doc/keywords.html#for - 用于计算移位次数

http://msdn.microsoft.com/en-us/library/f96c63ed(VS.80).aspx - 实际移动它

,玩它。它最终会起作用的!

It seems like your rotate to the right is RIGHT. 1 fell of the side and returned back again from the left?

Anyway, here are your ingredients:

http://tigcc.ticalc.org/doc/keywords.html#if - for determining if it is 'L' or 'R'

http://tigcc.ticalc.org/doc/keywords.html#for - for counting number of times to shift

and

http://msdn.microsoft.com/en-us/library/f96c63ed(VS.80).aspx - to actually shift it

Go, play with it. It WILL work eventually!

陈甜 2024-10-04 16:35:01

我建议使用unsigned int

#define DIR_LEFT 0
#define DIR_RIGHT 1

unsigned int rotateInt(unsigned int in, int amount, byte dir)
{
    return(dir == DIR_RIGHT ? (in >> amount) | ((in & ((0x01 << amount) - 1)) << (sizeof(unsigned int)*8 - amount)) : (in << amount)  | ((in & ~((sizeof(unsigned int)*8*8 - 1) >> amount)));
}

I recommend using an unsigned int.

#define DIR_LEFT 0
#define DIR_RIGHT 1

unsigned int rotateInt(unsigned int in, int amount, byte dir)
{
    return(dir == DIR_RIGHT ? (in >> amount) | ((in & ((0x01 << amount) - 1)) << (sizeof(unsigned int)*8 - amount)) : (in << amount)  | ((in & ~((sizeof(unsigned int)*8*8 - 1) >> amount)));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文