ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从晶体管开关到进制转换:一文彻底搞懂计算机底层二进制逻辑

从晶体管开关到进制转换:一文彻底搞懂计算机底层二进制逻辑 1. 从“开关”到“数字”为什么我们需要二进制如果你拆开过任何一台现代电子设备无论是手机、电脑还是智能手表你都会发现它的核心是一块布满微小元件的电路板。这些元件特别是晶体管本质上就是一个个微小的“开关”。它们只有两种状态开有电流通过和关无电流通过。计算机的一切复杂运算从播放一段视频到运行一个庞大的程序归根结底都是通过操控这数以亿计的“开关”的“开”与“关”来实现的。那么如何用“开”和“关”来表示我们人类世界丰富多彩的信息呢比如数字、文字、颜色、声音答案就是二进制。二进制是一种计数系统它和我们日常使用的十进制一样是一种表示数字的方法只不过它只使用两个符号0和1。你可以把“0”想象成电路的“关”状态把“1”想象成“开”状态。通过将无数个0和1进行排列组合计算机就能编码出几乎无限的信息。所以理解二进制不仅仅是理解一种数学概念更是理解现代数字世界运行的最底层逻辑。它一点也不神秘就像我们天生会用十个手指头十进制数数一样自然。这篇文章我将用一个完全从零开始的视角带你彻底搞懂二进制是什么以及它和我们熟悉的十进制、乃至其他进制如八进制、十六进制之间是如何轻松转换的。我的目标是即使你没有任何计算机基础看完也能立刻上手操作真正“一看就会”。2. 进制的本质每一位的“权重”游戏在深入二进制之前我们必须先建立一个核心概念位权。这是理解所有进制转换的万能钥匙。我们最熟悉的十进制Decimal使用了0-9这十个符号。当我们写一个十进制数比如365时我们本能地知道它表示“三百六十五”。但为什么是三百六十五呢我们来拆解一下最右边的5在个位它的权重是10⁰ 1所以它代表5 * 1 5。中间的6在十位它的权重是10¹ 10所以它代表6 * 10 60。最左边的3在百位它的权重是10² 100所以它代表3 * 100 300。最后我们把所有位的值加起来300 60 5 365。这里的“10”就是十进制的基数。每一位的权重都是基数的次幂从右向左次幂从0开始递增。现在我们把基数从“10”换成“2”就得到了二进制Binary。二进制只使用0和1两个符号。那么二进制数1011代表多少呢套用同样的“位权”法则基数 2。从右向左从最低位开始第0位最右边的权重是2⁰ 1。第1位的权重是2¹ 2。第2位的权重是2² 4。第3位最左边的权重是2³ 8。现在计算1011最右边位第0位是11 * 1 1右数第二位第1位是11 * 2 2右数第三位第2位是00 * 4 0最左边位第3位是11 * 8 8总和8 0 2 1 11(十进制)。所以二进制数1011就等于十进制数的11。看是不是和十进制原理一模一样只是把“逢十进一”换成了“逢二进一”。注意在书面表达时为了区分不同进制我们常在数字右下角用下标注明基数例如1011₂表示二进制11₁₀表示十进制。在编程中常用0b1011表示二进制11或0d11表示十进制。2.1 为什么是0和1一个生活化的类比你可以把二进制的一个“位”bit想象成一盏灯。这盏灯只有两种状态亮1和灭0。一盏灯能表达的信息很有限只能表示“是/否”、“开/关”。但如果我们有8盏灯排成一排呢比如亮灭亮灭灭亮灭亮10100101。这8盏灯的状态组合就能表示出2⁸ 256种不同的图案足以给256种不同的东西编号比如给键盘上的每个字符分配一个独一无二的二进制编码这就是ASCII码的基本思想。计算机的内存和硬盘就是由海量这样的“小灯”晶体管或磁畴组成的。每一个“小灯”就是一个比特bit。8个比特构成一个字节Byte这是计算机信息处理的基本单位。你文件的大小如15.3MB本质上就是在说这个文件占用了大约1500万个“8盏灯”的组合。3. 核心转换实战二进制与十进制的互转掌握了“位权”概念后进制转换就变成了简单的数学计算。我们分两个方向来攻克。3.1 二进制转十进制“按权展开求和即可”这其实就是我们刚才做的事情。步骤非常固定写出二进制数例如11010.101。注意二进制也有小数点原理相通。标出每位权重以小数点为界向左是整数部分向右是小数部分。整数部分从右向左从离小数点最近的一位开始权重依次是2⁰, 2¹, 2², 2³, 2⁴...小数部分从左向右从离小数点最近的一位开始权重依次是2⁻¹, 2⁻², 2⁻³...即1/2, 1/4, 1/8...每位乘以其权重。将所有乘积相加。实战演练将11010.101₂转换为十进制。整数部分11010从右向左0*2⁰0,1*2¹2,0*2²0,1*2³8,1*2⁴16整数部分和16 8 0 2 0 26小数部分.101从左向右1*2⁻¹0.5,0*2⁻²0,1*2⁻³0.125小数部分和0.5 0 0.125 0.625合并26 0.625 26.625所以11010.101₂ 26.625₁₀。实操心得整数部分转换几乎不会出错但小数部分容易混淆权重顺序。记住口诀“小数点后第一位权重是1/20.5”就不会错了。多练两个例子比如0.11₂ 0.75₁₀(1/2 1/4)0.001₂ 0.125₁₀(1/8)就能形成肌肉记忆。3.2 十进制转二进制“除2取余逆序排列”与“乘2取整顺序排列”这是稍微需要一点技巧的地方但方法非常机械。我们需要把整数部分和小数部分分开处理。整数部分转换除2取余法目标将十进制整数29转换为二进制。 步骤用29除以2得到商14余数1。这个余数就是二进制最低位最右边。用上一步的商14继续除以2得到商7余数0。用7除以2得到商3余数1。用3除以2得到商1余数1。用1除以2得到商0余数1。当商为0时停止计算。现在从下往上从最后一次除法向第一次除法读取余数1 1 1 0 1。所以29₁₀ 11101₂。为什么是“逆序排列”因为第一次除法得到的是最低位的余数最后一次除法得到的是最高位的余数。我们写数字总是从高位写到低位所以必须倒过来读。小数部分转换乘2取整法目标将十进制小数0.625转换为二进制。 步骤用0.625乘以2得到1.25。整数部分为1这个“1”就是二进制小数点后的第一位。取上一步结果的小数部分0.25继续乘以2得到0.5。整数部分为0这是二进制小数点后的第二位。取小数部分0.5乘以2得到1.0。整数部分为1这是第三位。此时小数部分已为0转换结束。顺序读取每次乘法的整数部分1 0 1。所以0.625₁₀ 0.101₂。合并演练将26.625₁₀转换为二进制。整数部分26用除2取余法得到11010。过程26/213余0 13/26余1 6/23余0 3/21余1 1/20余1 逆序11010小数部分0.625用乘2取整法得到.101。合并11010.101₂。这验证了我们之前二进制转十进制的正确性。注意事项小数转换有时会无限循环比如0.1₁₀在二进制中是一个无限循环小数0.0001100110011...₂。这就是为什么在金融等需要精确计算的领域使用二进制浮点数如编程中的float或double类型表示十进制小数时可能会产生微小的精度误差这是底层原理决定的需要在编程时特别注意。4. 扩展视野八进制与十六进制——二进制的“快捷包装”直接读写一长串0和1对人类来说非常不友好容易出错。例如101100111000₂这个数看起来就令人头疼。为了解决这个问题程序员们引入了八进制和十六进制它们本质上是二进制的“缩写”或“快捷表示法”。为什么是八和十六因为8 2³16 2⁴。这意味着一个八进制位正好对应三位二进制位一个十六进制位正好对应四位二进制位。转换起来可以“分组打包”极其方便。4.1 二进制与八进制的互转“三位一组不足补零”二进制转八进制以小数点为界分别向左、向右将二进制数每三位分成一组。最左整数部分或最右小数部分不足三位时用0补足。将每一组的三位二进制数用“位权求和”的方法转换为一个十进制数字这个数字只能是0-7因为三位二进制最大是111₂7₁₀。这个0-7的数字就是八进制的一位。示例将10110011.0111₂转换为八进制。分组整数部分10110011从右向左分组010110011最左边补一个0。小数部分.0111从左向右分组011100最右边补两个0。每组转十进制010₂ 0*4 1*2 0*1 2₈110₂ 1*4 1*2 0*1 6₈011₂ 0*4 1*2 1*1 3₈011₂ 3₈100₂ 4₈合并263.34₈。八进制转二进制更简单把上述过程反过来。将八进制数的每一位独立地转换成一个三位的二进制数不足三位的高位补0然后拼接起来即可。示例将47.52₈转换为二进制。4₈ 100₂7₈ 111₂5₈ 101₂2₈ 010₂合并100111.101010₂整数部分的小数点前的0可省略小数部分末尾的0可省略但保留有助于理解即100111.10101₂。4.2 二进制与十六进制的互转“四位一组不足补零”十六进制需要16个符号0-9不够用所以引入了A-F或a-f来表示10-15。即0,1,2,3,4,5,6,7,8,9,A(10),B(11),C(12),D(13),E(14),F(15)。转换逻辑和八进制完全一样只是从“三位一组”变成了“四位一组”。二进制转十六进制示例将1101011100.10111₂转换为十六进制。分组补零整数部分1101011100001101011100最左边补两个0。小数部分.1011110111000最右边补三个0。每组转十六进制0011₂ 3₁₆0101₂ 5₁₆1100₂ C₁₆1011₂ B₁₆1000₂ 8₁₆合并35C.B8₁₆。十六进制转二进制将每一位十六进制数展开为四位二进制数。示例将2F.A5₁₆转换为二进制。2₁₆ 0010₂F₁₆ 1111₂A₁₆ 1010₂5₁₆ 0101₂合并00101111.10100101₂即101111.10100101₂。经验技巧在编程、看内存数据或者网络数据包时十六进制比二进制友好得多。看到一个十六进制数0xDEADBEEF程序员能很快地将其拆解为二进制进行分析。而0x前缀是C语言、Java等编程语言中表示十六进制常量的常用方式。记住几个常见的对应关系能极大提升效率0xF1111,0xA1010,0xC1100,0x50101。4.3 十进制与八/十六进制的互转有两种路径路径一推荐十进制 - 二进制 - 八/十六进制。利用我们已经掌握的技能以二进制为桥梁。这对于理解本质和心算很有帮助。路径二直接法十进制转八/十六进制整数部分采用“除8取余”或“除16取余”法小数部分采用“乘8取整”或“乘16取整”法。原理和十进制转二进制完全相同只是基数换了。但计算除16取余时余数可能大于9需要用A-F表示。八/十六进制转十进制直接使用“位权求和”法基数为8或16即可。示例路径一将254₁₀转换为十六进制。先转二进制254₁₀ 11111110₂。二进制转十六进制1111 1110₂ F E₁₆。所以254₁₀ 0xFE。示例路径二将0x3D7₁₆转换为十进制。使用位权求和0x3D7 3*16² D*16¹ 7*16⁰ 3*256 13*16 7*1 768 208 7 983₁₀。5. 避坑指南与高频问题排查理解了原理和基本方法后在实际转换和概念理解上还有一些常见的“坑”。5.1 混淆“数”与“数的表示”这是一个根本性的概念问题。“一百”这个数量是客观存在的但表示它的方式可以多种多样100十进制、1100100二进制、144八进制、64十六进制。它们都是同一个数的不同“衣服”。在进行进制转换时我们是在改变表示方式而不是改变数本身的值。时刻记住这一点可以避免很多混乱。5.2 小数转换中的无限循环与精度取舍如前所述很多在十进制中有限的、整洁的小数如0.1在二进制中却是无限循环的。这会导致转换过程无法终止使用乘2取整法时小数部分永远不为0。存储时必然丢失精度计算机的存储空间是有限的只能截取无限循环二进制小数的一部分来近似表示。如何处理明确需求如果只是理论计算或手工验证可以保留分数形式或指出其循环性如0.1₁₀ ≈ 0.0001100110011...₂。设定精度在实际应用如编程中必须预先设定一个精度。例如规定“保留到二进制小数点后10位”。当乘2取整后的小数部分小于某个阈值如10⁻⁶时就停止计算。使用专用数据类型在需要高精度十进制计算的领域如财务应使用专门的数据类型如Java的BigDecimalPython的Decimal而不是原生的二进制浮点数float,double。5.3 补码计算机中负整数的表示法我们上面讨论的都是无符号正整数。计算机如何表示负数呢最常用的方案是补码。这略微超出了“浅显易懂”的范畴但它是二进制应用中至关重要的一环有必要了解其思想。核心思想用固定位数比如8位表示一个数。在这个范围内让负数与其对应的正数相加等于一个模2ⁿn是位数。8位二进制范围00000000到11111111共256个数。模2⁸ 256。如何得到一个负数的补码以-5为例假设用8位表示写出其正数5的8位二进制原码00000101。按位取反0变11变0得到反码11111010。反码加1得到补码11111011。验证00000101(5) 11111011(-5的补码) 1 00000000。由于我们只有8位最高位的1溢出了结果就是00000000即0符合“正负相加为0”的直观概念。避坑提示补码的最高位最左边一位是符号位。0表示正数或零1表示负数。但注意10000000这个补码表示的是-128而不是-0因为0只有一种表示00000000。这是补码设计的一个巧妙之处它统一了0的表示并且让加减法可以用同一套电路来实现。5.4 手工转换的常见计算错误位权记错特别是小数部分容易把2⁻¹记成0.1而不是0.5。牢记小数点后第n位的权重是2⁻ⁿ。分组错误二进制转八/十六进制时分组方向搞反或者补零的位置补错。记住以小数点为界向左整数部分和向右小数部分分别分组。整数部分从右向左数小数部分从左向右数。余数/整数部分顺序读错十进制转二进制时整数部分的余数要逆序读取小数部分的整数部分要顺序读取。一个简单的记忆方法是整数部分除基取余是从低位算到高位所以写结果时要倒过来小数部分乘基取整是从高位算到低位所以写结果时正着写就行。为了避免这些错误最好的方法就是在练习时每完成一步都做一次反向验证。比如把二进制转十进制的计算结果再用十进制转二进制的方法算回去看是否能得到原数。这是检验学习成果和发现错误的最有效手段。我自己在初学时就经常在分组上犯错后来养成了一个习惯在分组时先用笔在二进制数的小数点上下对齐位置然后每隔3位或4位轻轻画一条竖线作为分隔再开始转换。这个小小的动作能极大地提高准确性。进制转换本身并不复杂它更像是一种遵循固定规则的“手工活”熟练度是关键。理解了“位权”这个核心再通过反复练习固化“分组”、“补零”、“逆序”这些操作流程你就能在面对任何进制转换问题时都游刃有余。
返回列表