作者LPH66 (-6.2598534e+18f)
看板java
标题Re: [问题] 有关Java跟浮点数的问题
时间Sun Feb 28 02:02:42 2016
稍微翻了一下 Java spec
理论上你的数 (0x1.0p-1022) 应该 .toString() 的结果
必须至少要到 "2.2250738585072014e-308" 这麽多位才行
(Java API 有规定转换结果的精确度必须足以在转换回来时唯一决定为原数
http://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#toString-double-
可以看上述连结里有提到)
不过 0x1.0p-1022 这其实是个很特别的 double 浮点数:
它是所谓「正常表示」的 double 里最小的一个, 也就是 Double.MIN_NORMAL 这数
比它小的浮点数其储存方式跟一般的浮点数是不一样的
也因为这样, 有些手机架构里为了硬体设计和计算方便
有一个系统层的开关可以控制计算时要不要出现这种数
不要的话比 MIN_NORMAL 小的正数就会全部变成 0
这跟我们的问题的关连就在於
和 0x1.0p-1022 接近的两个浮点数
比它大的是 0x1.0000000000001p-1022
比它小的是 0x0.fffffffffffffp-1022 (←这个是非标准表示)
它们转换成十进位是: (多写几位以资比较)
0x1.0000000000001p-1022 = 2.22507385807201877...e-308
0x1.0p-1022 = 2.22507385807201383...e-308
0x0.fffffffffffffp-1022 = 2.22507385807200889...e-308
因此在一般的系统里, 单写 2.22507385807201 是会错误的辨认为最後一个的
所以 Java API 规定必须多输出一位以资判断
但在没有这种小小数的系统里
它只要能跟比它大的 0x1.0000000000001p-1022 分别就好
最接近 2.22507385807201e-308 的普通浮点数是 0x1p-1022 这就足够了
====
不过!以上讲了这麽半天, 有一个很重要的事实上面没有提到:
Java 语言定义里的 double 一直都是有这种小小数的标准 IEEE754 浮点数
所以照理来说只要照着 Java 的规定来的话
不管在哪里都应该得要能够使用小小数所以必须做这种分别才对
问题来了: 我们都知道 Android 的 Java 不是标准 Java
它只是拿了 Java 的 API 来自己定义着用而已 (那件官司相信大家记忆犹新)
所以如果 Android 那边并没有这种细节规定的话, 那就有可能产生不同结果
而事实上正是这样:
http://developer.android.com/reference/java/lang/Double.html#toString(double)
Android 官方的 Double.toString(double) 的说明里只有简短一行
Returns a string containing a concise, human-readable description of the
specified double value.
跟 Java 官方的 Double.toString(double) (上面的连结) 那麽落落长完全不同
所以根本原因其实并不是硬体结构的关系, 而是 API 规定上根本就不一样
因此所产生的结果也就有可能不一样了
(我有点怀疑 Android 版的 toString() 该不会是那种
在科学记号的小数点後面固定取 15 位的懒人但错误的实作法...
这样是并不足以使得转换回来的所有浮点数都是正确了的)
--
'You've sort of made up for it tonight,' said Harry. 'Getting the
sword. Finishing the Horcrux. Saving my life.'
'That makes me sound a lot cooler then I was,' Ron mumbled.
'Stuff like that always sounds cooler then it really was,' said
Harry. 'I've been trying to tell you that for years.'
-- Harry Potter and the Deathly Hollows, P.308
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.195.39.85
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1456596164.A.A41.html
※ 编辑: LPH66 (123.195.39.85), 02/28/2016 02:03:03
1F:推 jackyhuang: 推推 02/29 04:39
2F:推 Expsun: 推 02/29 19:34
3F:→ Lordaeron: 哪些是标准, 哪些是非标准呢? 可以列举一下吗? 02/29 20:52
4F:推 nekoga: 推 感谢详细解说! 03/01 22:15
5F:推 gmoz: NICE 03/03 17:59