发现 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 条回复
SuperMild
2016-06-05 21:15:31 +08:00
楼主你看的是哪本入门教材,书中肯定有说到这个的,就在说基本类型的数字类型那章
xuwenmang
2016-06-05 21:31:37 +08:00
@hard2reg C++你试试 1000000000000.2+1000000000000.2 还准不。
ericls
2016-06-05 21:36:14 +08:00
@hard2reg 输出和结果不一样很正常
realpg
2016-06-05 22:05:44 +08:00
mornlight
2016-06-05 22:14:37 +08:00
@realpg 你这输入法做多了 PY 交易
crazykuma
2016-06-05 22:23:22 +08:00
666 楼主这是没仔细看入门教程吧
随便一本入门里都有啊
justjavac
2016-06-05 22:40:39 +08:00
@hard2reg 输出 0.6 才是不正常的。 C++默认的浮点数输出有效位数为 6 ,即 setprecision(6)。
justjavac
2016-06-05 22:45:48 +08:00
@hard2reg 如果想要精确计算,使用 Decimal 之类的库。

但是要注意,初始化的时候不要使用

d = decimal(0.2)

而是用

d = decimal("0.2")

想想为什么?
OnTheRoad
2016-06-05 22:53:46 +08:00
除法不可避免的会产生误差。
当误差处于精度下限时,会做近似处理。
如:
<code>
print(0.3333333333333333 * 3)
# Output: 1.0
</code>
bdbai
2016-06-05 23:03:16 +08:00
@justjavac 我猜一下,前者表达式的精度已经损失了。对吗?
bramblex
2016-06-05 23:30:15 +08:00
@justjavac

输出 0.6 很正常, C++ 编译器的优化会把一些没什么意义的数值提前算出来,根本就轮不到运算……
bramblex
2016-06-05 23:36:18 +08:00
@hard2reg

输出 0.6 太正常不过了

a = 0.2 + 0.4 这行代码已经被 C++ 编译器编译优化成了 a = 0.6 了。所以在程序运行的时候根本就不存在 0.2 + 0.4 这个步骤,所以也就没有什么丢失精度的问题了。
clino
2016-06-05 23:43:17 +08:00
0.2 0.4 在 10 进制世界里是有理数 在二进制的世界里是无理数
所以二进制里无法用有限位数表达出 0.2 所以实际上计算机里没有对的 0.2 和 0.4 所以结果当然不一样 只是近似到误差非常小而已
winterbells
2016-06-05 23:51:00 +08:00
@pimin 其实 0.33333 3 循环乘以 3 等于 1 。。。
chairuosen
2016-06-05 23:57:42 +08:00
还是我大 JS 屌, 1/0.3 = 3.3333333333333335
ADMlN
2016-06-06 01:30:39 +08:00
'http://'+str(.1+.2)+'.com'
mikegreen7892003
2016-06-06 01:37:18 +08:00
https://en.wikipedia.org/wiki/IEEE_floating_point

楼主可以看看文档。浮点数在计算机内一般以二进制来存储。
浮点数的话,显示的结果和存储的内容不一定完全一致。只能说非常近似。
veficos
2016-06-06 01:39:55 +08:00
1 除以 0.3 是 3.3333 没错啊。。。。。。

1 / 0.3 == 10 / 3

这是数学问题好吧.....
veficos
2016-06-06 01:40:36 +08:00
换成分数去算就知道为什么了....
veficos
2016-06-06 01:46:45 +08:00
是我看错题义了。。。

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

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

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

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

© 2021 V2EX