不知道是不是所有语言都是这样的。。
#我用的是Python3 a = 1 / 3 # 这时候 a 打印出来应该是 0.333333333 b = 1 / a # 这时候打印 b 居然输出的是 3
这说明 Python 在内部是以分数的形式储存无限循环小数的?
还是我孤陋寡闻了。。。。
![]() | 1 clino 2016-06-05 19:58:20 +08:00 明明 1/3 是 0 >>> print 1/3 0 |
![]() | 3 Yc1992 2016-06-05 20:00:44 +08:00 明明 1/3 = 0 b = 1/0 = ∞ |
![]() | 5 publicID002 2016-06-05 20:02:18 +08:00 via Android 应该是输出的时候位数默认不多有舍入 |
6 wsy2220 2016-06-05 20:04:41 +08:00 浮点计算不保证结果精确的,换一个数甚至换一个机器结果就不一样了 |
![]() | 7 Kisesy 2016-06-05 20:08:03 +08:00 py 0.3333333333333333 3.0 go 0.3333333333333333 3 |
![]() | 8 shuax 2016-06-05 20:08:48 +08:00 ![]() print(2.999999999999999999999999999) |
9 billlee 2016-06-05 20:26:40 +08:00 不要依赖未定义行为 |
![]() | 10 clino 2016-06-05 20:32:10 +08:00 py3 的表现也合理啊 >>> print(1/3) 0.3333333333333333 >>> print(1/(1/3)) 3.0 >>> print(1/0.3333333333333333) 3.0 |
![]() | 11 justjavac 2016-06-05 20:34:10 +08:00 via Android 是你孤陋寡闻了。 浮点数的内部表示和浮点数的显示是两码事 |
![]() | 12 justjavac 2016-06-05 20:36:19 +08:00 via Android ![]() |
![]() | 13 pimin 2016-06-05 20:40:41 +08:00 via Android 我发现数学的一个坑 1/3=0.3333333... 0.33333*3<1 3*1/3=1 |
![]() | 14 ipconfiger 2016-06-05 20:44:07 +08:00 楼举不是计算机科班出身的吧, 先搞清楚二进制怎么存储浮点数就清楚了,如果我记得没错应该是在计算机组成原理的课本里有 |
![]() | 18 fy 2016-06-05 20:55:45 +08:00 日常又发现一个坑。。。 |
19 hard2reg OP @justjavac 貌似 JS 和 Python 都会出现 0.2 + 0.4 ≠ 0.6 的情况,但是我用 C++试了下输出的是 0.6 。请问这是为啥。。 float a; a = 0.2 + 0.4; cout << a << endl; 如果想要让 JS 和 Python 正确输出 0.6 改如何写。。 |
20 jimmyye 2016-06-05 21:13:13 +08:00 ![]() 要用 decimal 之类的库 |
21 SuperMild 2016-06-05 21:15:31 +08:00 via iPad 楼主你看的是哪本入门教材,书中肯定有说到这个的,就在说基本类型的数字类型那章 |
![]() | 24 realpg PRO ![]() ![]() |
26 crazykuma 2016-06-05 22:23:22 +08:00 666 楼主这是没仔细看入门教程吧 随便一本入门里都有啊 |
![]() | 27 justjavac 2016-06-05 22:40:39 +08:00 via Android @hard2reg 输出 0.6 才是不正常的。 C++默认的浮点数输出有效位数为 6 ,即 setprecision(6)。 |
![]() | 28 justjavac 2016-06-05 22:45:48 +08:00 via Android |
29 OnTheRoad 2016-06-05 22:53:46 +08:00 除法不可避免的会产生误差。 当误差处于精度下限时,会做近似处理。 如: <code> print(0.3333333333333333 * 3) # Output: 1.0 </code> |
31 bramblex 2016-06-05 23:30:15 +08:00 |
32 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 这个步骤,所以也就没有什么丢失精度的问题了。 |
![]() | 33 clino 2016-06-05 23:43:17 +08:00 via Android 0.2 0.4 在 10 进制世界里是有理数 在二进制的世界里是无理数 所以二进制里无法用有限位数表达出 0.2 所以实际上计算机里没有对的 0.2 和 0.4 所以结果当然不一样 只是近似到误差非常小而已 |
![]() | 35 chairuosen 2016-06-05 23:57:42 +08:00 还是我大 JS , 1/0.3 = 3.3333333333333335 |
![]() | 36 ADMlN 2016-06-06 01:30:39 +08:00 via Android 'http://'+str(.1+.2)+'.com' |
37 mikegreen7892003 2016-06-06 01:37:18 +08:00 https://en.wikipedia.org/wiki/IEEE_floating_point 楼主可以看看文档。浮点数在计算机内一般以二进制来存储。 浮点数的话,显示的结果和存储的内容不一定完全一致。只能说非常近似。 |
![]() | 38 veficos 2016-06-06 01:39:55 +08:00 1 除以 0.3 是 3.3333 没错啊。。。。。。 1 / 0.3 == 10 / 3 这是数学问题好吧..... |
![]() | 39 veficos 2016-06-06 01:40:36 +08:00 换成分数去算就知道为什么了.... |
![]() | 40 veficos 2016-06-06 01:46:45 +08:00 via Android 是我看错题义了。。。 |
41 introom 2016-06-06 01:59:56 +08:00 via Android 好吧,我也不懂。 是因为 0.333...被精确表示了么?别坑我, ieee745 没到无限循环小数那个份上啊。 那最后为什么会变成 3.0 ,而不是 2.9999999 呢? 要么是输出的时候四舍五入了,要么是 intel 的 fp 指令搞得鬼。 我更相信前者。 |
![]() | 42 justjavac 2016-06-06 08:03:08 +08:00 via Android @bramblex 编译器提前算的时候不是使用的浮点数?或者说编译器使用了其他当时计算的 0.2+0.4 的值 |
![]() | 43 tkisme 2016-06-06 09:36:28 +08:00 a=1/3.0 b=1/a |
![]() | 44 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 |
![]() | 45 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' ``` |
![]() | 48 magiclx 2016-06-06 09:54:40 +08:00 奇怪的是大家不知道数学上: 0.333...*3 = 1 ? |
49 Arnie97 2016-06-06 09:55:23 +08:00 via Android Haskell 大法好,有原生的分数类型。 |
![]() | 50 misaka19000 2016-06-06 10:16:00 +08:00 @realpg ... |
![]() | 52 BlackKey 2016-06-06 11:29:35 +08:00 via Android LZ 请去自行了解 IEEE754 |
![]() | 56 dixyes 2016-06-06 13:48:17 +08:00 via Android 还以为要讨论.3 循环乘 3 等于一的问题(同时因为.3 循环乘三等于.9 循环所以.9 循环等于一 |
![]() | 57 newton108 2016-06-06 15:37:06 +08:00 有几位是高中生吧? 浮点数运算和 0.99...=1 有任何关系么? |
![]() | 58 aREMbosAl 2016-06-06 17:21:39 +08:00 分数在内部存储的时候好像是精确的,显示出来是近似的。。 |
![]() | 59 mauve PRO 有什么不对吗? |