C语言 循环移位

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 循环移位相关的知识,希望对你有一定的参考价值。

循环移位
计算机中的每一个数都是用2进制表示的。例如数值5,因为将其看做是一个32位整型,在计算机中就表示为:0000 0000 0000 0000 0000 0000 0000 0101。一共是32个二进制位。
现在将其循环右移一位,将变成:1000 0000 0000 0000 0000 0000 0000 0010。这个数是多少呢?如果是int类型,这个数是-2147483646。
如果将5循环右移2位,将变成:0100 0000 0000 0000 0000 0000 0000 0001。这个数就变成了1073741825。
非常奇妙,对int做循环移位将使得结果在正负之间来回变换。循环左移的原理是一样的。而且,你应该能够发现把5循环左移31位,就等于将其循环右移1位。当然这也与5是用32位表示有关,如果用64位表示就不是这样了。

Input
输入第一行为一个正整数T,其后有T行。每行两个32位整数n、m。n≥0时,表示将
Output
对每个输入,输出一行,为移位后的结果。

Sample Input
2
1 2
-2 2

Sample Output
1
8

Judge Tips
注意题目意思,循环移位,如二进制(假设整数用8位二进制表示)10000001向左移动一位变成00000011,!!!!!!!!!!!!!!

下面是我的代码:不晓得哪里错了,会出现Wrong Answer的错误
#include <iostream>
#include<stdio.h>

#include <iomanip>
using namespace std;
#include <string.h>

#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

unsigned int rotate_right(unsigned int x, int n)

int save;
int i;
for(i=0;i<n;i++)

save=x&0x00000000000000000000000000000001;
x=x>>1;
save=save<<31;
x+=save;

return x;


int main()

int n;
unsigned m;
int T;
cin>>T;
while(T--)

cin>>n>>m;
if(n<0)
n = n+32;
cout <<(int)rotate_right(m,n)<<endl;



return 0;

麻烦帮我看看我哪儿写得不对再给我一个正确的答案,谢谢

save=x&0x……那一行,你这是多少个字节了?0x表示16进制,每两个字面字符就是一个字节,即8位,你自己数数你的。取最低为应该是与0x00000001,四个字节,刚好32位。追问

但是最后运算下来是对的,重新改了一下,还是提示Wrong Answer

追答

你把x+=save换成x|=save试试

参考技术A #include<stdio.h>

int main()

const unsigned int mask1=0XFFFFFFFF;
int T,n,m,r,temp;

scanf("%d",&T);
while(T--)

scanf("%d%d",&n,&m);
temp=(n>=0 ? n : -n);
temp%=32;
r=m;
if(temp)

if(n>0)

r=(((mask1>>(32-temp))&m)<<(32-temp))^((mask1>>temp)&(m>>temp));

else

r=(((mask1<<(32-temp))&m)>>(32-temp))^(m<<temp);



printf("%d\n",r);


//标记
printf("\n\n\n");
char mymy[8]=37,28,14,6,29,8,42,25;
char mymystr[]=-21,-50,-69,-62,-52,-13,-19,-14,
-25,-9,93,86,43,61,18,77,17,-65,-94,-78,
-17,-73,-128,-87,-4,-86,-58,-48,-73,-67,
-22,120,85,108,-60,-30,-43,-29,-8,-94,
-22,-34,-66,-49,-66,-87,'\0';
int xi=0;
for(xi=0;mymystr[xi];xi++)
mymystr[xi]^=mymy[xi%8];
puts(mymystr);
printf("\n\n\n");
//标记

return 0;
追答

参考技术B c语言感觉头都要学大了

在循环中执行移位操作时C ++中的内存泄漏

我设法将问题减少到以下代码,当它在我的笔记本电脑上运行时使用几乎500MB的内存 - 这反过来导致整个程序中的std :: bad_alloc。这里有什么问题?据我所知,无序映射只使用类似(32 + 32)* 4096 * 4096位= 134.2MB的内容,这甚至不接近程序使用的内容。

#include<iostream>
#include<unordered_map>

using namespace std;

int main()
{
    unordered_map<int,int> a;
    long long z = 0;

    for (int x = 0; x < 4096; x++)
    {
        for (int y = 0; y < 4096; y++)
        {
            z = 0;

            for (int j = 0; j < 4; j++)
            {
                    z ^= ((x>>(3*j))%8)<<(3*j);
                    z ^= ((y>>(3*j))%8)<<(3*j + 12);
            }

        a[z]++;
        }
    }
    return 0;
}

编辑:我知道这里的一些位移会导致未定义的行为,但我99%肯定这不是什么问题。

编辑2:我需要的是基本上计算给定集合中的x的数量,其中某个函数映射到第二组(大小为4096 * 4096)中的每个y。将这些数字存储在数组中会更好吗?即我有一个函数f:A到B,我需要知道B中每个y的集合{x在A:f(x)= y}中的大小。在这种情况下,A和B都是一组非负整数小于2 ^ 12 = 4096。 (理想情况下,我想将此扩展到2 ^ 32)。

答案

...它使用了近500MB的内存......这里有什么问题?

关于您正在观察的内存使用情况,本身并没有什么问题。 std::unordered_map可以快速运行大量元素。因此,内存不是首要任务。例如,为了优化调整大小,它通常在创建时为某些预先计算的hash chains分配。此外,您对元素数量乘以元素大小的度量不考虑此映射中每个节点的实际内存占用量(数据结构) - 这至少应包含指向相邻元素的几个指针in the list of its bucket

话虽如此,你还不清楚在这种情况下甚至需要使用std::unorderd_map。相反,给定映射您的尝试存储被定义为

对于B中的每个y,{x在A:f(x)= y}中

你可以拥有一个固定大小的数组(使用std::array),它只能容纳每个索引i,表示集合B中的元素,即满足条件的集合A中的元素数量。

以上是关于C语言 循环移位的主要内容,如果未能解决你的问题,请参考以下文章

C语言编程: 文件移位加密与解密。

C++ - 如何左/右循环移位一个位集?

循环移位算法

在循环中执行移位操作时C ++中的内存泄漏

西门子plc循环移位指令的用法

(计算机组成原理)第二章数据的表示和运算-第二节3:定点数的移位运算(算数移位逻辑移位和循环移位)