今天笔记记录聊一下孤尽老师为我们讲解的浮点数,确实是刷新了我对浮点数新的认识,希望各位小伙伴有机会也要多静下心来研究研究计算机底层的一些知识。
一些有趣的例子
请看如下图的例子1 ,大家猜猜输出结果是什么?
请再看下图的例子2,大家再猜猜输出结果是什么?
如果对计算机底层没有深刻的理解,答对的可能性可能非常低,大家肯定会按照自己的猜测去想答案,那么接下来我来公布正确答案
例子1:
例子2:
大家看到以上的结果是不是很懵逼啊,,,反正我是没有猜对ヽ(ー_ー)ノ。
那么接下来再来一个例子3,大家猜猜输出的结果是什么?
那么我来公布下输出内容如下:
很神奇,是不是啊,答案为什么不是0.1呢,这就要讲到神奇的浮点数了。
浮点数
单精度浮点数格式
从数学世界的科学计数法映射到计算机世界的浮点数时,数制从十进制改为二进
制,还要考虑内存硬件设备的实现方式。在规格化表示上存在差异,称谓有所改变,
指数称为〝阶码”,有效数宇称为“尾数",所以用于存储符号、阶码、尾数的二进
制位分别称为符号位、阶码位、尾数位。
1、规格化
0.4 = 4×10^-1
=0.4/2^-2 × 2^-2
=1.6×2^-2
0.3 = 3×10^-1
=0.3/2^-2 × 2^-2
=1.2×2^-2
2、尾数部分转为二进制
1.6=1.1001 1001 1001 1001 1001 100 1100110011001100110011001101
1.2=1.0011 0011 0011 0011 0011 001 10011001100110011001100110011
3、尾数截断,转为十进制
红色部分反转为十进制: 1.5999999046325684
红色部分反转为十进制: 1.1999999284744263
4、计算结果
0.4 = 0.3999999761581421
0.3 =0.29999998211860657
0.5f -0.4f = 0.09999999403953552
=0.099999994
回到JS
JS没有整形,只有Double浮点数:
Long类型有64位,传递给前端必须转换成州揱勃啟活
而Double只有16位有效数字,超过16位有效数字,就会被截断
最大能够精确表示的整形值:900719925474 0992=2 的53 次方
前后端设计与规约
【强制】 对于需要使用超大整数的场景,服务端一律使用 String 宇符串类型返回,禁止使用
Long 类型
说明:Java 服务端如果直接返回 Long 整型数据给前端,JS会自动转换为 Number 类型(注:此类型为双精度浮点数,表示原理与取值范围等同于 Java 中的 Double)。Long 类型能表示的最大值是2的 63 次方-1,在取值范围之内,超过2的53次方 (9007199254740992)的数值转化为 JS的Number 时,有些数值会有精度损失。扩展说明,在Long 取值范围内,任何2的指数次整数都是绝对不会存在精度损失的,所以说精度损失是一个概率问题。若浮点数尾数位与指数位空间不限,则可以精确表示任何整数,但很不幸,双精度浮点数的尾数位只有52 位。
反例: 通常在订单号或交易号大于等于 16 位,大概率会出现前后端单据不一致的情况,比如,“orderld”:362909601374617692, 前端拿到的值却是:362909601374617660.