草庐IT

【小记】二八十十六,进制团团转

SomeBottle的博客园站 2023-03-28 原文

这篇笔记咱主要写一下二进制、八进制、十进制、十六进制之间的互相转换。

Contents

前言

通过观察,我觉得二、八、十、十六进制数的互相转换可以总结为三大块:

  1. 十进制与其他进制互相转换
  2. 二进制与其他进制互相转换
  3. 十六进制与八进制的互相转换

话不多说,下面就按这三大块来归纳一下。

十进制与其他进制的互相转换

十进制到其他进制

整数部分

? 方法除以基数倒取余

比如16进制,除以的基数就是16

  1. “除以基数”指的是将十进制数不断除以目标进制对应的基数,直到0为止。

  2. “倒取余”指的是将每次相除得到的余数倒序排列,即转换为了目标进制的数。


  • [例] 10进制转换为8进制

    图中的红色箭头展示了“倒取余”的过程

    图中将十进制1145转换为了八进制2171

  • [例] 10进制转换为16进制

    图中的红色箭头展示了“倒取余”的过程

    图中将十进制14191转换为了十六进制376F

小数部分

不是所有的小数都能转换为其他进制。比如现代计算机采用二进制计数,有很多小数都没法准确地转换为二进制(只能取近似值),这也是为什么说现在计算机无法完全准确地表示小数。

? 方法乘以基数顺取整

比如2进制,对应的基数就是2

  1. “乘以基数”指的是不断将小数部分乘以目标进制对应的基数,直到小数部分0为止。

  2. “顺取整”指的是将每次相乘得到的数的整数部分顺序排列,即转换为了目标进制的数。


  • [例] 2进制转换为10进制

    图中的红色箭头展示了“顺取整”的过程

    图中将十进制0.375转换为了二进制0.011

其他进制到十进制

? 方法每一位数字乘上基数^对应指数(位权),然后相加求和

本图中的数值12C.1415926,是十六进制数。

上图中,基数是16,“对应指数”就是橙色标出的数。以小数点为分界,小数点左侧第一位的对应指数为0,而小数点右侧第一位的对应指数为-1

从低位向高位(图中从右向左),这个指数不断增大。

十六进制的基数是16,那么八进制的基数就是8,以此类推。

  • [例] 16进制转换为10进制

    图中将十六进制12C.14转换为了十进制300.078125

二进制与其他进制的互相转换

二进制和其他进制的互相转换就要方便多了。

二进制到其他进制

? 方法以小数点为界,向左右两侧,每几位读为一个数,不足的就补零

  • 关于这里的“每几位”,需要看要转换为哪个进制的数。比如转换为十六进制,其一位能表示0-F16种状态,需要用4个二进制位来表示,那么就是每4位一读。

    再比如八进制一位能表示0-78种状态,需要用3个二进制位来表示,那么就是每3位一读。

  • 关于补零,无论是从小数点左侧第一位开始往左每几位一读,还是从小数点右侧第一位开始往右每几位一读,都难免遇到“位数不够读”的情况,这个时候就需要补零。


  • [例] 二进制转换为十六进制

    图中将二进制1001001.011转换为了十六进制49.6

    • 红色箭头展示了以小数点为分界,分别往左右进行读取。左侧从低位向高位,而右侧从高位向低位
    • 图中括号展示了补零的过程。100011都不足4位,按照读取方向,分别在其左方右方补零。
    • 最后,每4位一读,用十六进制表示出来,就得到了最后的结果。
  • [例] 二进制转换为八进制

    图中将二进制1001101.1011转换为了八进制115.54

    • 具体做法和上面一个例子一致,这里不多赘述。

其他进制到二进制

? 方法:每位读为几位二进制数

  • 关于这里的“每位读为几位二进制数”,需要看转换前是哪个进制的数。比如原本是十六进制,其一位能表示0-1516种状态,需要用4个二进制位来表示,那么就是每位读为4位二进制数

  • 附一个对照表:

    八进制位 ←对应的二进制 十六进制位 ←对应的二进制
    0 000 0 0000
    1 001 1 0001
    2 010 2 0010
    3 011 3 0011
    4 100 4 0100
    5 101 5 0101
    6 110 6 0110
    7 111 7 0111
    - - 8 1000
    - - 9 1001
    - - A 1010
    - - B 1011
    - - C 1100
    - - D 1101
    - - E 1110
    - - F 1111

    实际应用中,可以根据8421码来进行计算,不用死记硬背。

    比如三位二进制101, 对应421,转换为十进制就是4+1=5
    再比如四位二进制1010, 对应8421,转换为十进制就是8+2=10


  • [例] 八进制转换为二进制

    图中将八进制67.23转换为了二进制110111.010011

    • 每一位八进制位读成3位二进制数(一位八进制位能表达8种状态,需要3位二进制位来表示)

    不想用8421码其实也没问题,八进制和十六进制的每一位数其实可以看作是十进制整数,使用除2倒取余的方法能将其逐位展开为二进制数
    (本质上还是按位读取,每位读为几位二进制数)

    比如上图中,原八进制数中的63分别可以用除2倒取余的方法展开为110011,和8421码得出的结果一致。

十六进制与八进制的互相转换

十六进制和八进制之间无法直接转换:

  • 如果要把十六进制数转换为八进制数,就需要先将十六进制转换为十进制或二进制,进而再转换为八进制。
  • 八进制转为十六进制也需要用十进制或二进制“过渡一下”

八进制转十六进制的例子

  • 通过二进制进行间接转换

    上图中我将八进制数12.450先转换为了二进制数001010.100101000,再转换为了十六进制数A.94

    二进制和其他进制互相转换的方法在上面已经介绍过了,这里就不多赘述。

  • 通过十进制进行间接转换

    上图中我将八进制数12.450先转换为了十进制数10.578125,再转换为了十六进制数A.94

    • 这里再提一嘴:十进制转为其他进制时,需将整数小数分而治之。

    十进制和其他进制互相转换的方法在上面也已经介绍过了,这里就不多赘述。

十六进制转八进制的例子

  • 通过二进制进行间接转换

    上图中我将十六进制数C.98先转换为了二进制数1100.10011000, 再转换为了八进制数14.46

    可以看到,十六进制转八进制和八进制转十六进制的过程是十分类似的。

  • 通过十进制进行间接转换

    上图中我将十六进制数C.98先转换为了十进制数12.59375, 再转换为了八进制数14.46

冷笑话

这位老伙计为什么要在万圣节前夜穿上圣诞节的服装呢?

答:因为 Oct 31 = Dec 25

October(十月) 31 是万圣节前夜,December(十二月) 25 是圣诞节。
但是在这也可以理解成Octal(八进制) 31 = Decimal(十进制) 25 (*^_^*)

有关【小记】二八十十六,进制团团转的更多相关文章

  1. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  2. Ruby - 如何将消息长度表示为 2 个二进制字节 - 2

    我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi

  3. ruby - 如何在 Ruby 中将负整数转换为二进制 - 2

    问题1:我无法通过以下方式找到将负整数转换为二进制的方法。我应该像这样转换它。-3=>"11111111111111111111111111111101"我在下面试过:sprintf('%b',-3)=>"..101"#..appearsanddoesnotshow111111bit.-3.to_s(2)=>"-11"#Thisjustadds-tothebinaryofthepositiveinteger3.问题2:有趣的是,如果我使用在线转换器,它告诉我-3的二进制是“0010110100110011”。"11111111111111111111111111111101"和"001

  4. Ruby#index 方法 VS 二进制搜索 - 2

    给定一个元素和一个数组,Ruby#index方法返回元素在数组中的位置。我使用二进制搜索实现了我自己的索引方法,期望我的方法会优于内置方法。令我惊讶的是,内置的在实验中的运行速度大约是我的三倍。有Rubyist知道原因吗? 最佳答案 内置#indexisnotabinarysearch,这只是一个简单的迭代搜索。但是,它是用C而不是Ruby实现的,因此自然可以快几个数量级。 关于Ruby#index方法VS二进制搜索,我们在StackOverflow上找到一个类似的问题:

  5. ruby - 如何在 Ruby 中返回整数的固定长度二进制表示? - 2

    我知道我可以使用Fixnum#to_s将整数表示为二进制格式的字符串。但是1.to_s(2)生成1而我希望它生成00000001。我怎样才能使所有返回的字符串都以零作为填充到8个字符?我可以使用类似的东西:binary="#{'0'*(8-(1.to_s(2)).size)}#{1.to_s(2)}"if(1.to_s(2)).size但这看起来不是很优雅。 最佳答案 使用字符串格式。"%08b"%1#=>"00000001" 关于ruby-如何在Ruby中返回整数的固定长度二进制表示?

  6. ruby - 在 Ruby 中将字符串转换为十六进制 - 2

    我正在尝试使用Ruby将二进制文件转换为十六进制。目前我有以下内容:File.open(out_name,'w')do|f|f.puts"constunsignedintmodFileSize=#{data.length};"f.puts"constcharmodFile[]={"first_line=truedata.bytes.each_slice(15)do|a|line=a.map{|b|",#{b}"}.joiniffirst_linef.putsline[1..-1]elsef.putslineendfirst_line=falseendf.puts"};"end这是以下代

  7. ruby - 如何从二进制数据的偏移量开始读取? - 2

    我有一个类似C的结构:SomeStruct:lenVarsstring:namestring:lname#...end我在:Person之前有一堆偏移量和长度。所有偏移量和长度都描述了:Person结构中的数据。如何从指定的偏移量、给定的长度或直到下一个偏移量开始读取数据? 最佳答案 寻求偏移1234,然后将32个字节读入Strings:open'some-binary-file','r'do|f|f.seek1234s=f.read32#thoinyourcase,somethinglike:o=aBinData_object.r

  8. ruby - 十六进制字符串到 Ruby 中的 signed int 转换 - 2

    如何在ruby​​中将十六进制字符串转换为32位有符号整数?例如a="fb6d8cf1"#hexstring[a].pack('H*').unpack('l')#fromthedocumentationitunpackstoits32bitsignedint它转换为-242455045但实际答案是-76706575你能指出我做错了什么吗? 最佳答案 您似乎遇到了字节序问题。这给出了期望的结果:[a].pack("H*").unpack("l>")#=>[-76706575]["038a67f90"].pack("H*").unpac

  9. Ruby to_s 转换为二进制(参数中的 Splat 运算符) - 2

    如果我运行以下代码,前两行会返回我所期望的结果。然而,第三个返回2的二进制表示。2.to_s#=>"2"2.to_s*2#=>"22"2.to_s*2#=>"10"我知道在调用to_s时传入2会将我的输出转换为二进制,但为什么to_s忽略第三个中的*案件?如果有任何不同,我正在运行Ruby1.9.2。 最佳答案 对,正如Namida已经提到的,Ruby解释2.to_s*2作为2.to_s(*2)因为方法调用中的圆括号在Ruby中是可选的。这里的星号就是所谓的splatoperator.这里唯一令人费解的问题是为什么*2的计算结果为2

  10. ruby - 如何验证字符串是 Ruby 中的正确十六进制值? - 2

    我正在用Ruby编写一个6502汇编器。我正在寻找一种方法来验证字符串形式的十六进制操作数。我知道String对象提供了一个“十六进制”方法来返回一个数字,但是我遇到了一个问题:"0A".hex#=>10-avalidhexadecimalvalue"0Z".hex#=>0-invalid,producesazero"asfd".hex#=>10-Why10?Iguessitreads'a'firstandstopsat's'?输入一堆乱码会得到一些奇怪的结果。我需要的是一种方法来首先验证该值是合法的十六进制字符串。我在玩正则表达式,并意识到我可以做到这一点:trueif"0A"=~/

随机推荐