进制运算
-
进制拾遗
二进制:0、1
八进制:0、1、2、3、4、5、6、7
十进制:0、1、2、3、4、5、6、7、8、9
十六进制:0、1、2、3、4、5、6、7、8、9 、A、B、C、D、E、F(分别表示10、11、12、13、14、15)
1 #10进制转换8进制,以0o开头,逢7进1 2 print(oct(1)) #结果为:0o1 3 print(oct(2)) #结果为:0o2 4 print(oct(3)) #结果为:0o3 5 print(oct(7)) #结果为:0o7 6 print(oct(8)) #结果为:0o10 7 print(oct(15)) #结果为:0o17 8 print(oct(16)) #结果为:0o20 9 print(oct(64)) #结果为:0o100 10 11 #0进制转换16进制,以0x开头,逢16进1 12 print(hex(1)) #结果为:0x1 13 print(hex(3)) #结果为:0x3 14 print(hex(9)) #结果为:0x9 15 print(hex(10)) #结果为:0xa 16 print(hex(11)) #结果为:0xb 17 print(hex(15)) #结果为:0xf 18 print(hex(16)) #结果为:0x10 19 print(hex(31)) #结果为:0x1f
为何使用 16 进制
16进制与2进制的换算
-
2进制换算为16进制
四合一法(从二进制的小数点为分界点,向左(或向右)每四位取成一位)
注意16进制的表示法(用字母H后缀表示或者用0X前缀表示)
在向左(或向右)取四位时,取到最高位(最低位)如果无法凑足四位,就可以在小数点的最左边(或最右边)补0,然后再进行换算。
-
16进制转换为二进制
一分为四法(一个十六进制数分成四个二进制数,用四位二进制按权相加,最后得到二进制,小数点依旧)
二进制数与十六进制数之间如何互相转换:https://jingyan.baidu.com/album/47a29f24292608c0142399cb.html?picindex=1
字符编码回顾
字符编码回顾:http://www.cnblogs.com/alex3714/articles/7550940.html
-
编码的种类情况
- ASCII 占1个字节,只支持英文
- GB2312 占2个字节,支持6700+汉字
- GBK GB2312的升级版,支持21000+汉字
- Shift-JIS 日本字符
- ks_c_5601-1987 韩国编码
- TIS-620 泰国编码
- 由于每个国家都有自己的字符,所以其对应关系也涵盖了自己国家的字符,但是以上编码都存在局限性,即:仅涵盖本国字符,无其他国家字符的对应关系。应运而生出现了万国码,他涵盖了全球所有的文字和二进制的对应关系,
- Unicode 2-4字节 已经收录136690个字符,并还在一直不断扩张中。
-
Unicode 的作用
直接支持全球所有语言,每个国家都可以不用再使用自己之前的旧编码了。
unicode包含了跟全球所有国家编码的映射关系。
-
Unicode 的缺点
使用unicode表示一个字符,太浪费空间,比原来ASCII表示多占用了1倍的空间。
存储和网络传输时消耗资源。
-
UTF
为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间。
- UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
- UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。
- UTF-32: 使用4个字节表示所有字符;
总结:UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。
字符怎么存到硬盘上的?
无论以什么编码在内存里显示字符,存到硬盘上都是2进制
注意:存到硬盘上时是以何种编码存的,再从硬盘上读出来时,就必须以何种编码读。
字符编码的转换
虽然现在国际语言是英语 ,但大家在我们自己的国家说的依然是自己国家的语言。编码也是一样的,虽然有了 unicode 与 utf-8 ,但是各个国家依然在使用自己的编码。
比如中国的windows系统默认编码依然是gbk,而不是utf-8。
但是我们出了国,你就得会国际语言英语,不然没方法沟通呀!编码也是一样的,如果中国的软件出口到美国,他们的电脑上并没有gbk编码,那么在美国人的电脑上就会显示乱码。
若想让中国的软件可以正常的在美国人的电脑上显示该怎么办呢?
-
让美国人的电脑上装上 gbk 编码。
-
编码时以 utf-8 或 unicode 编码。
第1种方法几乎是不可能实现的,如此看来还是第2种方法比较简单些。
但是第二种方法也只能是针对新开发的软件, 如果是之前就是以gbk编码的软件,重新编码成utf-8格式也会费很大力气,那要怎么办呢?
unicode其中一个功能是其包含了跟全球所有国家编码的映射关系。
也就是说,你写的是gbk的“路飞学城”,但是unicode能自动知道它在unicode中的“路飞学城”的编码是什么。那就意味着,无论你以什么编码存储的数据 ,只要你的软件在把数据从硬盘读到内存里,转成unicode来显示,就可以了。
由于所有的系统、编程语言都默认支持unicode,那你的gbk软件放到美国电脑 上,加载到内存里,变成了unicode,中文就可以正常展示了。
unicode与gbk的映射表 :http://www.unicode.org/charts/
Python3的执行流程
-
Python3的执行过程
1、’解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成unicode。
2、把代码字符串按照语法规则进行解释。
3、所有的变量字符都会以unicode编码声明。
-
python3编码转换过程
实际代码演示,在py3上 把你的代码以utf-8编写, 保存,然后在windows上执行。
s = '路飞学城' print(s)
上面的utf-8编码之所以能在windows gbk的终端下显示正常,是因为到了内存里python解释器把utf-8转成了unicode。但是这只是python3, 并不是所有的编程语言在内存里默认编码都是unicode,比如python2 , 它的默认编码是ASCII。
python2解释器仅以文件头声明的编码去解释你的代码,加载到内存后,并不会主动帮你转为unicode,也就是说,你的文件编码是utf-8,加载到内存里,你的变量字符串就也是utf-8, 这意味着,你以utf-8编码的文件,在windows是乱码。
乱是正常的,不乱才不正常,因为只有2种情况 ,你的windows上显示才不会乱:
1、字符串以GBK格式显示
2、字符串是unicode编码
-
python3编码转换语法
python3 可以自动把文件编码转为 unicode必定是调用了什么方法。这个方法就是,decode(解码) 和 encode(编码)。
1、UTF-8 --> decode 解码 --> Unicode
2、Unicode --> encode 编码 --> GBK / UTF-8
记住下图规则
Python3通过查看编码映射表确定编码类型
-
如何验证编码转对了呢?
1、查看数据类型,Python2里面有专门的unicode类型
2、查看unicode编码映射表
-
通过字节长度判断(utf-8一个中文占3字节,gbk一个占2字节)
“路飞学城”的unicode编码的映射位置是 u'\u8def\u98de\u5b66\u57ce' 。
“路飞学城”对应的GBK编码是'\xc2\xb7\xb7\xc9\xd1\xa7\xb3\xc7' 。2个字节一个中文,"路" 的二进制 "\xc2\xb7"是4个16进制,正好2字节,拿它到unicode映射表里对一下, 发现是G0-4237,并不是\xc2\xb7。
再查下“飞” \u98de ,对应的是G0-3749, 跟\xb7\xc9也对不上。
虽然对不上, 但好\xc2\xb7 和G0-4237中的第2位的2和第4位的7对上了,“飞”字也是一样,莫非巧合?
把他们都转成2进制显示试试
1 路 2 C 2 3 8 4 2 1 8 4 2 1 4 <strong>1 1 0 0 0 0 1 0</strong> 5 6 B 7 7 8 4 2 1 8 4 2 1 8 <strong>1 0 1 1 0 1 1 1</strong> 9 10 11 飞 12 B 7 13 8 4 2 1 8 4 2 1 14 1 0 1 1 0 1 1 1 15 16 C 9 17 8 4 2 1 8 4 2 1 18 1 1 0 0 1 0 0 1
但是这个“路”还是跟 G0-4237 对不上啊, 但如果把‘’路‘’ \xc2\xb7 的每个二进制字节的左边第一个bit变成0试试,然后发现加起来就真的是4237了。
之所以是这样,是因为GBK的编码表示形式决定的。因为GBK编码在设计初期就考虑到了要兼容ASCII,即如果是英文,就用一个字节表示,2个字节就是中文。
但如何区别连在一起的2个字节是代表2个英文字母,还是一个中文汉字呢?
中国人决定,2个字节连在一起,如果每个字节的第1位(也就是相当于128的那个2进制位)如果是1,就代表这是个中文,这个首位是128的字节被称为高字节。 也就是2个高字节连在一起,必然就是一个中文。
因为0-127已经表示了英文的绝大部分字符,128-255是ASCII的扩展表,表示的都是极特殊的字符,一般没什么用,所以中国人就直接拿来用了。
问:那为什么上面 "\xc2\xb7"的2进制要把128所在的位去掉才能与unicode编码表里的G0-4237匹配上呢?
这只能说是unicode在映射表的表达上直接忽略了高字节,但真正映射的时候 ,肯定还是需要用高字节的哈。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步