我在哪里可以找到C的C换档指南?[英] Where can I find a bit shifting guide for C?

本文是小编为大家收集整理的关于我在哪里可以找到C的C换档指南?的处理方法,想解了我在哪里可以找到C的C换档指南?的问题怎么解决?我在哪里可以找到C的C换档指南?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我已经看过 什么是位移(位移动)操作员它们如何工作? ,但我仍然发现很难理解的一点转移的概念.

有人可以将我指向C中刻度转移的更基本指南的方向吗?我希望这会很长时间,因为它需要涵盖整个主题.

我正在学习 c编程语言 (aka) K&R),这就是目的的目的,因此我可以进行练习.我了解基础知识,但我仍然无法做到正确的位移动操作.

这是K&R的练习,使我陷入困境

练习2-6:编写一个函数setBit(x,p,n,y),该函数返回x的x,该n位在位置p的位置p设置为y的最右n位,而其他位则保持不变.

练习2-7:写一个函数反转(x,p,n),该函数返回x的x,n位在位置p倒置下开始(即1个更改为0,反之亦然),使其他位保持不变.<<<<<<<<<<./p>

练习2-8:编写一个函数rightrot(x,n),该功能返回整数x的值x向右侧旋转的右侧位置

练习2-9:在两个补充编号系统中,x&=(x-1)在x中删除了最右边的1位.解释原因,并使用此观察来编写更快的BitCount版本.

这些是K&R(C编程语言)书中的练习.这是最好的C书,但是我很难理解有点变化,所以我在这些练习方面遇到了问题.

推荐答案

位移动仅是字面意思的意思是:在给定的序列中移动所有位.

您要记住的是,每个小数号(例如6、7、3、2)被表示为计算机内存中的一系列序列.因此,如果您在C代码中找到类似的东西:

(7 >> 1)

这意味着7的基础二进制表示中的位应向右移动1个位置.

我认为您引用的链接中的解释很明显.也许自己在纸上写下一系列碎屑,并像引用的链接一样操纵它们可以帮助您.

或者,也许您还不了解计算机如何在内部使用数字.在这种情况下,在学习之前,您需要阅读有关此的内容.

其他推荐答案

您将需要工具包中更多的工具来回答这些问题,而不是转移.

我认为您需要非常基础,了解数字在二进制中的表示.然后,您将需要考虑如何在该数字中设置和清除特定的位,或同时设置一组位.您需要知道如何测试以查看是否设置了某些零件以及有关掩盖的设置.您必须能够使用位运算符以及XOR,反转等进行上述所有操作.

.

然后,您将需要了解转移 - 通过特定数量的空间向左和向右移动位.您将想知道剩下的"空"碎片会发生什么.它充满了1还是0?什么时候填充1或0?

谷歌搜索"位操作教程"似乎提出了一些有希望的结果.但是这里有一些基础知识可以测试自己,以确保您了解

// 1234 in hexadecimal. Do you understand this is not 1234 in decimal? Do you understand
// how specifying in hex makes it easier to think about the binary representation?
unsigned short i = 0x1234;
// Flip all the bits in 0x1234
printf("%04x", ~i);

// Test - Is the most significant bit set?
// mask is a binary number with the most significant bit set. Do
// you understand why this is so?
unsigned short mask = 0x8000;
if ((mask & i) == mask)
{
    printf("bit set!");
}
else
{
    printf("bit cleared!");
}

// Set the most significant bit
i = i | mask;
printf("Set the MSB of i, check it out: %i\n", i)

// Set the second most significant bit
// Do you see how by shifting mask right one it becomes the next most significant bit?
i = i | (mask >> 1);

祝你好运!

其他推荐答案

在纸上写一些碎片,考虑从一端擦除它们,然后添加更多.与小学不同,并在乘以10时将小数点移动.

您的所有C功能都将移动零.

所以

x = y << 3;

表示左侧三个位,右侧的新位都是全部零.左边的三个位进入"位桶":

x = z >> 2

在右侧丢失两个位,并在左侧添加两个零.

您会发现丢失功能的K&R练习是什么.在处理器类型中,您的变化功能比C或其他任何高级语言都要多.

您的旋转功能在一端移动的位置移动.

因此,数字0xD以这种方式向右旋转一个位将是0xe,因为最小显着的位是1,所以将1101转移到右侧,右侧的1变成左侧1110的1.<<<<<<

有时您会在 alu "> alu 中旋转.假设携带位的钻头在其中零,您旋转0xD lite 0 1101叶1 0110 A 0x6.再旋转一个,0 1011,您将获得0xB等等.

为什么您要旋转您要问的进位?对于更大的数字,假设您有四个位寄存器,并且想进行8位移动,假设每个字母都是BCDE FGHI的位,其中a是进位,而其他四组则是四个寄存器.首先将左寄存器旋转通过携带E ABCD FGHI,然后通过进位旋转右寄存器 我abcd efgh.很酷;我们只是使用4位移动功能进行了8位移动.

如果您在启动之前清除了进位点(通常有一个指令,或者您总是可以做诸如添加0+0或其他保证清除一点的事情),您将拥有

i 0bcd efgh

如果您在64位数字上操作的32位指令集,则与C轮换功能无关.

处理器通常具有c的偏移,而零移动,shift abcd左右给出bcd0 shift abcd abcd右两个给出00AB.

.

这导致了带有现代处理器的年轻人的一些问题……考虑一下此类问题,因为整数鸿沟都受到处理器的支持,并且可以在单个时钟周期中运行.回到我们有分裂或何时分配数十个时钟到数百个时钟之前,但是轮班是单个时钟,您将使用转移的所有功率进行2​​个分隔或乘以乘以.以剩下两个的数字0x0d偏移,您获得0b00001101 <<2 = 0b00110100或0x34. 0xD为13小数,0x34为52小数. 52是13倍的四倍.四个是2到2的功率2.转移两个与乘以4相同.

.

这两种方式工作; 0x34向右移动2为0xD,但这是问题.当您陷入负数时,将数字减去4 0xFC,现在将其除以两个.使用C 0xFC >> 1将给出0x7E,但0x7e为+126小数. -4/2 = 126?

如何

问题是C在零中移动.您会发现一些处理器具有算术转移,这与逻辑转移不同.算术偏移保持最高位,因此,如果您正在使用一个符号数字(例如0BQWER),并且您将其算术算了一点点,您将获得0BQQQE.最高位都转移到下一个位并留在原处.

再次移动0BQQQW,依此类推.现在,算术偏移将在零变化,而不是最低的显着位,因此0BQWER左移动一个是0BWER0.这很有意义. -4移动左一个是0xf8,是-8,-4乘以-8为-8,所以是正确的.

因此,您会发现某些处理器只有右移动右移动,而不是左侧.有些人允许您指定ASL,但是当他们组装它时,将其替换为LSL(左逻辑偏移),并且谁知道有些人实际上可能具有单独的操作码,即使它是相同的函数.我认为可能有一些ASL和ASR和LSR,但没有LSL.

只需使用纸和铅笔就可以解决问题.从实数作为示例开始,然后进行抽象.想要一点点旋转0x1234,假设

0001001000110100  write out the bits
x0001001000110100 shift right one
0000100100011010  because this is a rotate fill in the new bit with the bit that fell off on the prior operation

现在想向右移动两个位

0000100100011010
xx0000100100011010
1000001001000110

我将如何在c?

中进行一次旋转
unsigned int rotate_right_one ( unsigned int x )
{
  unsigned int y;
  y = x & 1;  // Save the bit that is about to fall off the right
  x >> = 1;  // Logical rotate one bit
  x |= y<<31; // This assumes that unsigned int is 32 bits.
  return(x);
}

要旋转更多,您可以多次调用此功能或思考掩码并在上方移动,以及该功能如何工作.

还要注意,某些处理器只有一个旋转函数.例如,考虑一下.我有一个四位寄存器,我旋转5位.我得到了什么?

abcd
bcda  first rotate
cdab  second
dabc  third
abcd  fourth
bcda  fifth

单个旋转的左旋转是什么样的?

abcd
bcda  one bit left.

五个位寄存器上的五个右侧与左5-4 = 1相同.像ASL一样,某些处理器会让您对操作进行编码,但是汇编器将操作用另一个旋转作为旋转数量旋转.

.

对于某些人来说,合乎逻辑的手术就像指针理解一样艰难,但这是一个基本的操作,如果您学习并使用它,您将在竞争之前或周围的那些人.

这是一个示例,计算一些变量中的位数:

for(count=0, r=1; r; r<<=1) 
    if(r&some_variable) 
        count++;

了解代码行,您正处于学习C和逻辑位操作方面.

本文地址:https://www.itbaoku.cn/post/359107.html