发现 Python 的一个坑。。。

2016-06-05 19:54:58 +08:00
 hard2reg

不知道是不是所有语言都是这样的。。

#我用的是Python3
a = 1 / 3
# 这时候 a 打印出来应该是 0.333333333
b = 1 / a
# 这时候打印 b 居然输出的是 3

这说明 Python 在内部是以分数的形式储存无限循环小数的?

还是我孤陋寡闻了。。。。

9199 次点击
所在节点    Python
60 条回复
introom
2016-06-06 01:59:56 +08:00
好吧,我也不懂。
是因为 0.333...被精确表示了么?别坑我, ieee745 没到无限循环小数那个份上啊。

那最后为什么会变成 3.0 ,而不是 2.9999999 呢?

要么是输出的时候四舍五入了,要么是 intel 的 fp 指令搞得鬼。

我更相信前者。
justjavac
2016-06-06 08:03:08 +08:00
@bramblex 编译器提前算的时候不是使用的浮点数?或者说编译器使用了其他当时计算的 0.2+0.4 的值
tkisme
2016-06-06 09:36:28 +08:00
a=1/3.0
b=1/a
coddmajes
2016-06-06 09:36:54 +08:00
最后解释一下整数的除法为什么也是精确的。在 Python 中,有两种除法,一种除法是 /:

>>> 10 / 3
3.3333333333333335
/除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:

>>> 9 / 3
3.0
还有一种除法是 //,称为地板除,两个整数的除法仍然是整数:

>>> 10 // 3
3
你没有看错,整数的地板除 //永远是整数,即使除不尽。要做精确的除法,使用 /就可以。

因为 //除法只取结果的整数部分,所以 Python 还提供一个余数运算,可以得到两个整数相除的余数:

>>> 10 % 3
1
无论整数做 //除法还是取余数,结果永远是整数,所以,整数运算结果永远是精确的。

来自廖雪峰的网站 http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431658624177ea4f8fcb06bc4d0e8aab2fd7aa65dd95000
Clarencep
2016-06-06 09:48:49 +08:00
浮点数当然是有误差的, LZ 可以试试这样子:


```

>>> '%.50lf' % (0.3)
'0.29999999999999998889776975374843459576368331909180'
>>> '%.50lf' % (1/3)
'0.33333333333333331482961625624739099293947219848633'


>>> '%.50lf' % (0.33333333333333333)
'0.33333333333333331482961625624739099293947219848633'
>>> '%.50lf' % (1/0.33333333333333333)
'3.00000000000000000000000000000000000000000000000000'

>>> '%.50lf' % (0.3333333333333333)
'0.33333333333333331482961625624739099293947219848633'
>>> '%.50lf' % (1/0.333333333333333)
'3.00000000000000310862446895043831318616867065429688'

```
Arnie97
2016-06-06 09:51:56 +08:00
@clino 是分数,不是无理数。无理数是无限不循环小数。
clino
2016-06-06 09:53:52 +08:00
@Arnie97 好吧 概念模糊 数学都还给体育老师了...
magiclx
2016-06-06 09:54:40 +08:00
奇怪的是大家不知道数学上: 0.333...*3 = 1 ?
Arnie97
2016-06-06 09:55:23 +08:00
Haskell 大法好,有原生的分数类型。
misaka19000
2016-06-06 10:16:00 +08:00
@realpg ...
isno
2016-06-06 10:31:23 +08:00
@justjavac 博客质量不错啊
BlackKey
2016-06-06 11:29:35 +08:00
LZ 请去自行了解 IEEE754
menc
2016-06-06 11:45:32 +08:00
@justjavac 你的博客写得真麻烦,不如直接看 IEEE754
justjavac
2016-06-06 12:33:27 +08:00
@menc IEEE754 是专业,我是业余
hard2reg
2016-06-06 13:41:27 +08:00
@bramblex soga~ thx
dixyes
2016-06-06 13:48:17 +08:00
还以为要讨论.3 循环乘 3 等于一的问题(同时因为.3 循环乘三等于.9 循环所以.9 循环等于一
newton108
2016-06-06 15:37:06 +08:00
有几位是高中生吧?
浮点数运算和 0.99...=1 有任何关系么?
aREMbosAl
2016-06-06 17:21:39 +08:00
分数在内部存储的时候好像是精确的,显示出来是近似的。。
mauve
2016-06-06 19:51:39 +08:00
有什么不对吗?
ivechan
2016-06-06 20:07:42 +08:00
@pimin 0.33333333~~~~~=1/3,前提是 3 是无穷

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/283686

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX