Python 中的进制转换

老齐 2021-09-15 12:41:39
Python 腾讯云 转换 进制


*本文是书稿中的一部分,主要介绍了 Python 中进制转换的实现方法。更多内容请参阅 www.itdiffer.com 我的个人网站 ”

3.4 进制转换

前面诸节所用到的整数、浮点数、分数,均是“十进制”的数,这符合数学和日常生产生活的多数习惯。而计算机则不然,它使用的是二进制(参阅第1章1.2节)。从数学角度看,用于实现记数方式的进位制除了十进制、二进制之外,还有八进制、十六进制、六十进制等。同一个数字,可以用不同的进位制表示。在数学和计算机原理的资料中,会找到如何用手工的方式实现各种进位制之间的转换——这些内容不在本书范畴,此处重点介绍使用 Python 内置函数实现进制转换,并由此观察一个貌似“ bug ”的现象。

3.4.1 转换函数

在 Python 内置函数中(如3.3节中的表3-3-1所示)提供了实现数值转换的函数,下面依次介绍。

1. 十进制转换为二进制

内置函数 bin() 能将十进制的整数转换为二进制,例如:

>>> bin(2)
'0b10'
>>> bin(255)
'0b11111111'
>>> bin(-3)
'-0b11'

bin() 只能对十进制的整数进行转换,所返回值是用字符串(参阅第4章4.2节)表示的二进制数字(简称“二进制字符串”),如图3-4-1所示,其中 0b 是二进制字符串前缀。

图3-4-1 返回结果组成

若将十进制的浮点数转化为二进制,是否可以用 bin()?不能!官方文档中很明确地指出:Convert an integer number to a binary string prefixed with “0b”.(https://docs.python.org/3/library/functions.html#bin),还可以试试:

>>> bin(0.1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'float' object cannot be interpreted as an integer

不能使用 bin() 函数将十进制浮点数转化为二进制,但可以用别的方法实现,只不过此处暂不探讨,可以作为读者的一个思考题。

2. 十进制转换为八进制

内置函数 oct() 可以将整数转化为以 0o 为前缀的八进制字符串,如:

>>> oct(8)
'0o10'
>>> oct(256)
'0o400'

注意参数依然必须是整数。

3. 十进制转换为十六进制

内置函数 hex() 可以将整数转化为以 0x 为前缀的十六进制字符串,如:

>>> hex(16)
'0x10'
>>> hex(255)
'0xff'

在十六进制中,一般用数字

0

9

和字母

A

F

表示。在 hex() 返回的十六进制字符串中,所用的

A

F

的字母均为小写。

对于十进制的浮点数,虽然 hexo() 不能使用,但浮点数对象有一个方法可以实现向十六进制的转换。

>>> float.hex(0.1)
'0x1.999999999999ap-4'
>>> 0.1.hex()
'0x1.999999999999ap-4'

其实,这里得到的十六进制字符串与十进制浮点数 0.1 并非严格相等。

4. 二进制转换为十进制

如果在交互模式中直接输入二进制数,比如 01,Python 解释器并不接受——所接受的是十进制数。

>>> 01
File "<stdin>", line 1
01
^
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers

当然,有的读者可能输入的是 11 ,不会报错,但 Python 把它看做二进制 11 了吗?没有!它显然被 Python 认定为十进制的整数十一了。

>>> 11
11
>>> type(11)
<class 'int'>

但是,如果在交互模式中这样输入二进制数字:

>>> 0b11
3
>>> 0b10
2
>>> 0b11111111
255

注意,输入的不是“二进制字符串”,而是在二进制数前面写上了前缀 0b,表示当前所输入的是二进制数,返回值则是对应的十进制整数。这种方式仅限于交互模式,在程序文件中不能这样做——千万不要将 >>> 0b11 复制到 .py 文件中。

更常用的方法是使用内置函数 int() ,在3.3.1节中提到过, int(x, base=10) -> integer 会在本节介绍,就是这里:

>>> int('0b10', 2)
2
>>> int('11111111', 2)
255

其中的'0b10''11111111' 都是二进制字符串,并且要设置参数 base=2 ,即说明参数中的数字是二进制数字——不明确“告诉” Python ,它不知道 '0b10''11111111' 表示的是二进制字符串。

同样用 int() 函数,也能将八进制、十六进制的整数转换为十进制的整数。

>>> int('0xff', base=16)
255
>>> int('0o10', base=8)
8

3.4.2 不是 bug

在3.3.1节介绍内置函数 round() 时引用了官方文档的一个示例:

>>> round(2.675, 2)
2.67

该文档中明确说明:“This is not a bug”。那是什么呢?

类似的现象,其实还有,比如:

>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
>>> 0.1 + 0.1 + 0.1 - 0.2
0.10000000000000003

这些计算中都有一些“误差”,也不是 Python 的 bug。

由于计算机是执行二进制计算的,要完成十进制数字的计算,不得不将十进制数字转化为二进制。对于十进制的整数而言,都有精确的二进制数对应。但是,对于浮点数就不完全有精确的二进制数对应了。

例如,

0.1

转化为二进制是:

0.0001100110011001100110011001100110011001100110011...

。这个二进制数不精确等于十进制数

0.1

。同时,计算机存储的位数是有限制的,所以,就出现了上述“误差”。

这种问题不仅在 Python 中会遇到,在所有支持浮点数运算的编程语言中都会遇到,所以它不是 Python 的 bug 。

明白了原因后,该怎么解决呢?就 Python 的浮点数运算而言,大多数计算机每次计算误差不超过

\frac{1}{2^{53}}

。对于大多数任务来说,通过“四舍五入”(round() 函数,参阅3.3.1节)即能得到期望的结果。

但是,如果遇到“较真”的要求,怎么办?

>>> import decimal
>>> a = decimal.Decimal('0.1')
>>> b = decimal.Decimal('0.2')
>>> a + b
Decimal('0.3')
>>> float(a + b)
0.3

decimal 是 Python 标准库的一个模块,官方地址是 https://docs.python.org/3/library/decimal.html 。如上述代码示例,分别创建了与浮点数

0.1

0.2

对应的两个对象( decimal.Decimal 类型),它们之间相加,所得结果即为准确的

0.3

。但是这样计算的速度要低于浮点数运算。

decimal 模块不仅能解决上述计算“误差”问题,还有很多用途,比如某个业务要求所有计算结果必须有

3

位有效数字(注意与“四舍五入”不同),可以这样实现:

>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 3
>>> Decimal(1) / Decimal(7)
Decimal('0.143')
>>> Decimal(3) * Decimal(math.pi) ** 2
Decimal('29.6')

此外,decimal.Decimal 对象亦有支持常见计算的方法。建议读者在学习完第8章和第9章,再认真阅读此模块的官方文档,并练习使用其中的各个方法。

*自学建议 编程语言中是基于计算机基本原理而存在的,因此,建议读者在学习本书之余——学有余力,阅读有关计算机基本原理的书籍,这样不仅对编程语言,乃至于以后的工作实际都会大有裨益。例如对于本节提到的“进制转换带来的计算误差”问题,要想“知其所以然”,就不得不求助于计算机基本原理的知识。 我在个人网站 www.itdiffer.com 和微信公众号【老齐教室】都会发布有关计算机原理的内容,读者可查阅参考。 ”

本文分享自微信公众号 - 老齐教室(itdiffer) ,作者:老齐

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间: 2021-09-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

版权声明
本文为[老齐]所创,转载请带上原文链接,感谢
https://cloud.tencent.com/developer/article/1877623

  1. Python - Programmation orientée objet - pratique (6)
  2. Python - Programmation orientée objet - réflexion hasattr, GetAttr, GetAttr, delattr
  3. Python - Programmation orientée objet - _Dict
  4. Python - pydantic (2) Modèle imbriqué
  5. Non-ASCII character ‘\xe5‘ in file kf1.py on line 4, but no encoding declared; see http://python.or
  6. python笔记(一)
  7. Non - ASCII character 'xe5' in file kf1.py on Line 4, but no Encoding declared;Voirhttp://python.or
  8. Notes Python (1)
  9. Talk about how JMeter executes Python scripts concurrently
  10. In Beijing, you can't see the moon in the Mid Autumn Festival. Draw a blood red moon in Python
  11. Un des pandas crée un objet
  12. Machine learning | unitary regression model Python practical case
  13. Draw a "Lollipop chart" with Excel and python
  14. Python uses scikit learn to calculate TF-IDF
  15. Getting started with Python Basics_ 3 conditional statements and iterative loops
  16. Python dynamic properties and features
  17. 云计算开发:Python内置函数-min()函数详解
  18. [Python skill] how to speed up loop operation and numpy array operation
  19. 雲計算開發:Python內置函數-min()函數詳解
  20. Développement de l'informatique en nuage: explication détaillée de la fonction intégrée python - min ()
  21. 从0起步学Python(附程序实例讲解)第1讲
  22. 从0起步学Python(附程序实例讲解)第1讲
  23. Apprendre Python à partir de 0 (avec des exemples de programme) leçon 1
  24. Apprendre Python à partir de 0 (avec des exemples de programme) leçon 1
  25. With Python, I'll take you to enjoy it for a month when the Mid Autumn Festival is coming
  26. You can't write interface software in Python! Which software on sale has no UI?
  27. Python国内外原题解析及源码1~15
  28. Python实现长篇英文自动纠错~
  29. Python implémente la correction automatique des erreurs en anglais long
  30. Analyse des problèmes originaux et code source de Python au pays et à l'étranger 1 ~ 15
  31. 一张思维导图学Python之表白
  32. Python教学中课程思政建设的研究探索2
  33. Recherche sur la construction idéologique et politique du Programme d'études dans l'enseignement Python 2
  34. Une présentation de la cartographie mentale Python
  35. Python高级用法总结(8)-函数式编程
  36. Python + Mirai development QQ robot starting tutorial (2021.9.9 test is valid)
  37. Python Advanced use Summary (8) - functional Programming
  38. How to get started with Python and share learning methods for free. All you want to know is here
  39. Python + Mirai development QQ robot starting tutorial (2021.9.9 test is valid)
  40. Python趣味编程中(PPT适合青少儿和零基础学习Python)
  41. Python基础第1讲(含代码、Python最新安装包、父与子的编程之旅:与小卡特一起学Python中文版)
  42. 用 Python 增强 Git
  43. Python基礎第1講(含代碼、Python最新安裝包、父與子的編程之旅:與小卡特一起學Python中文版)
  44. Base Python leçon 1 (y compris le Code, le dernier paquet d'installation Python, le voyage de programmation parent - enfant: apprendre la version chinoise de python avec le petit Carter)
  45. Dans la programmation amusante Python (ppt pour les jeunes enfants et l'apprentissage de base zéro Python)
  46. 非常好的题目详解Python字典的用法
  47. Python teaches you to build wechat push live Betta reminder from 0 (single room simplified version)
  48. Python 协程与 JavaScript 协程的对比
  49. 手把手带你用Python实现一个量化炒股策略
  50. Main dans la main pour mettre en œuvre une stratégie quantitative de spéculation boursière en python
  51. Comparaison des coproductions Python et JavaScript
  52. 【python种子项目ppc】一行代码生成项目与开发详细指导
  53. Docker 部署一个用 Python 编写的 Web 应用
  54. Python - poetry(4)管理环境
  55. Python - poetry(2)命令介绍
  56. [Python Seed Project PPC] a line of Code Generation Project and Development detailed guidance
  57. Introduction à la commande python - Poetry (2)
  58. Python - Poetry (4) Management Environment
  59. I collected Banhua's spatial data set in Python. In addition to meizhao, I found her other secrets again!
  60. I modified ban Hua's boot password in Python and found her secret after logging in again!