【问题标题】:Where to learn about "bit"? [closed]在哪里了解“比特”? [关闭]
【发布时间】:2011-08-30 19:59:12
【问题描述】:

我正在尝试查找一些详细讨论位的书籍或资源,以便例如我能够将数字(如 16)转换为位。我目前是一名高中生,每当阅读编程书籍时,我几乎可以理解除位/位运算符部分之外的所有内容。我只是不知道它是如何工作的,为什么人们还要发明比特和字节:(。因此,我希望你们能给我一些资源建议,讨论如何将数字/字符转换为比特。

【问题讨论】:

  • 计算机系统,程序员的视角。

标签: c++ c architecture bit-manipulation bit


【解决方案1】:

计算机世界中的所有事物都只能用“0”和“1”字符串表示。例如,int 类型一般有 32 位,long long 类型有 64 位,n 位类型可以表示 0 到 2^n-1 之间的数字。

此外,像 '>'、'&' 或 '|' 这样的位操作比计算机中的算术运算更快,因为它使用硬件来执行此操作。很多代码都可以据此进行优化。

将一个int转化为二进制,首先你要知道的是任何数都可以用2^0,2^1,2^2....2^k的组合来表示:比如6=2^2+ 2^1 , 13 = 2^3+2^2+2^0 以此类推,那么 6 和 13 可以写成 0110 和 1101。其实这是一道数学题。

如果你想了解更多关于位操作的信息,我想你可以去google或wiki搜索而不是这里。

【讨论】:

    【解决方案2】:

    我读过的关于二进制数学和位移的最好的书之一是Hacker's Delight. 这实际上是一本关于超优化的书。我强烈建议您阅读它,如果材料太复杂,请非常缓慢地完成它。我之前不得不为爱好操作系统重写标准库函数,如 strlen(),而这本书救了我的命。

    【讨论】:

    • 超优化是一种枚举代码序列的技术,以便找到计算所需结果的最优序列 (en.wikipedia.org/wiki/Superoptimization)。这和 Hacker's Delight 没有任何关系,Hacker's Delight 是使用数学和逻辑来获得适合各种计算的良好算法,而不是愚蠢地枚举所有代码序列。
    【解决方案3】:

    我建议学习对 z80、PIC 或其他微处理器进行编程。然后你就会明白位和字节是从哪里来的。不过,在你这样做之前,你可能想弄脏数字电子产品。位存在的原因是因为数字电子设备只有两个值的信号,即开和关,因此是 1 和 0,或一个位。

    【讨论】:

      【解决方案4】:

      http://en.wikiversity.org/wiki/Bitwise_operators

      http://en.wikipedia.org/wiki/Binary_numbers

      一旦您学会了如何以 2 为底数(二进制或“位”)表示数字,按位运算符就很容易理解了。

      我只举一个简单的例子:

      设 m=31532=111101100101100 和 n=12325=11000000100101。

      那么n & m(按位与-二元运算符)的结果是:

      (如果n(i)和m(i)都为1,则结果为1,否则为0)

      111101100101100
      011000000100101
      ===============
      011000000100100
      

      n 的结果 | m(按位或 - 二元运算符)是:

      (如果n(i)和m(i)为0,则结果为0,否则为1)

      111101100101100
      011000000100101
      ===============
      111101100101101
      

      n ^ m(按位异或 - 二元运算符)的结果是:

      (如果 n(i) 和 m(i) 中的一个为 1,但不是两者,则结果为 1,否则为 0)

      111101100101100
      011000000100101
      ===============
      100101100001001
      

      ~n(按位非 - 一元运算符)的结果是:

      (如果 n(i)=1 则结果为 0,否则为 1)

      111101100101100
      ===============
      000010011010011
      

      设k=3,n>>k(按位右移)的结果为:

      111101100101100
      ===============
      000111101100101
      

      他们只是向右移动了 k=3 次。这有效地将数字除以 2^k=8。它通常被编译器用作优化。

      反之,设k=3,n

      111101100101100
      ===============
      101100101100000
      

      他们只是向左移动了 k=3 次。这有效地将数字乘以 2^k=8。这里需要注意的一点是,由于 32bit 整数最多只能容纳 2^32-1,出现了算术溢出,即高 k 位被截断。

      您只需要仔细查看并找出这些模式。

      它们在编程中很重要,因为它们通常用于设置/清除标志值。

      由于 int32 有 32 个二进制数字,它可以包含多达 32 种不同类型的布尔标志(0 表示假,或 1 表示真)

      我想这就是它。它们相当直观。

      【讨论】:

        【解决方案5】:

        不完全是一本书,但Wikipedia article on Binary representations of numbers 涉及过多的细节。 converting between bases 上有一个不错的部分,您可能会觉得有用。

        There are some scary clever tricks to working with bitfields and binary representations of numbers;来自stb.h header

        int stb_bitcount(unsigned int a)
        {
           a = (a & 0x55555555) + ((a >>  1) & 0x55555555); // max 2
           a = (a & 0x33333333) + ((a >>  2) & 0x33333333); // max 4
           a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
           a = (a + (a >> 8)); // max 16 per 8 bits
           a = (a + (a >> 16)); // max 32 per 8 bits
           return a & 0xff;
        }
        
        unsigned int stb_bitreverse8(unsigned char n)
        {
           n = ((n & 0xAA) >> 1) + ((n & 0x55) << 1);
           n = ((n & 0xCC) >> 2) + ((n & 0x33) << 2);
           return (unsigned char) ((n >> 4) + (n << 4));
        }
        
        unsigned int stb_bitreverse(unsigned int n)
        {
          n = ((n & 0xAAAAAAAA) >>  1) | ((n & 0x55555555) << 1);
          n = ((n & 0xCCCCCCCC) >>  2) | ((n & 0x33333333) << 2);
          n = ((n & 0xF0F0F0F0) >>  4) | ((n & 0x0F0F0F0F) << 4);
          n = ((n & 0xFF00FF00) >>  8) | ((n & 0x00FF00FF) << 8);
          return (n >> 16) | (n << 16);
        }
        

        简直太棒了。 :)

        【讨论】:

        • 看来我今晚要头疼了……:(
        【解决方案6】:

        回答您的部分问题...

        只需在 Google 搜索框中输入 16 to binary。如果你真的很勇敢,你可以输入16 to hex 来得到你的十六进制答案。 :)

        【讨论】:

          【解决方案7】:

          尝试使用谷歌搜索“二进制算术”。这是一个 pretty good article,可以帮助您入门。

          【讨论】:

          • 谢谢皮特!我忘了维基百科... :)
          【解决方案8】:

          您的问题与编码或任何特定编程语言无关,而与数学有关,尤其是代数和数字系统。然后下一阶段将是处理器 x86 架构基础知识,而不是您可以转到编程语言。

          顺便说一句:通常有关 x86 病毒的书籍是了解 CPU 工作原理的一个很好的开端,但如果不了解 base-2 和 base-16 系统,您将无法从中获得太多收益。

          【讨论】:

          • 一本关于计算机病毒的书可能是学习编程等基础知识的最糟糕的方法之一。
          • “通常有关 x86 病毒的书籍是了解 CPU 工作原理的良好开端” - 请理解阅读。我还没有看到很多提到寄存器、位级处理等的编程语言书籍……而且 CPU 架构指南对于新手来说通常非常复杂。如果他想写我的第一个 Hello World - 继续从书架上拿第一本书,但如果他对基础知识更感兴趣,我强烈推荐 Virus way :)
          【解决方案9】:

          它们之间没有区别,因为我觉得它们无法比较。有点被“发明”了,因为计算机只知道两种状态,开(1)或关(0)。一个字节就是 8 位。我不知道有哪本书专门讨论位或字节,但是如果您查看有关逻辑设计、数字基础或任何有关硬件架构的书籍,您会发现有关位及其使用方式的更多信息.汇编语言处理的位也比高级语言多得多,因此您可能也想研究一下。

          【讨论】:

          • 感谢您的快速回复,我已经编辑了问题!你有没有详细解释位的资源?例如如何将数字转换为位...
          • 在“现代商品系统”上一个字节是 8 位。并非总是如此:)
          • @phngcv 我已经编辑了我的答案并提出了更多建议。我也不完全理解位,我自己的字节也很好。直到我在大学上了一门逻辑设计课程。我提供了一些建议,您可以更轻松地找到所需的深入信息。
          • 并不是说计算机只“知道两种状态”,而是真的很简单在最微小的单元(一点)只有的地方创建内存开关;但它真的很难,通常不需要在这个分辨率下寻址内存(但系统允许它)。数字电路也在信号功率中利用了这一点——有 ON/OFF(虽然 OFF 可能并不总是 0v,而 ON 通常“大于”)。
          猜你喜欢
          • 1970-01-01
          • 2011-08-13
          • 2022-01-17
          • 2011-05-22
          • 1970-01-01
          • 2013-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多