[关闭]
@JunQiu 2018-09-18T13:00:08.000000Z 字数 3679 阅读 1607

Js_内部数值的表示及浮点数运算、浮点数:IEEE754/定点数

summary_2018/07 todo(IEEE指数位的偏移问题) language_js pocc(计组)


1、日常工作

2、技术学习
  1. 双精度64位表示:S E M
  2. 符号位S:第 1 位是正负数符号位(sign),0代表正数,1代表负数
  3. 指数位E:中间的11位存储指数(exponent),用来表示次方数(指数是一个整数,一般来说整数会采用补码存储,但是补码存储不能方便地进行浮点数的比较以及运算,于是exponent采用biased exponent = exponent + bias
  4. 尾数位M:最后的 52 位是尾数(mantissa),超出的部分自动进一舍零
  5. ###Example:176.0625表示为单精度浮点数:
  6. 1、先将176.0625转换为二进制数
  7. 小数点前:176 / 2 = 88 余数为 0
  8. 88 / 2=44 余数为 0
  9. 44 / 2 =22 余数为 0
  10. 22 / 2= 11 余数为 0
  11. 11 / 2 =5 余数为 1
  12. 5 / 2=2 余数为 1
  13. 2 / 2 =1 余数为 0
  14. 1/ 2=0 余数为 1 商为0,结束。
  15. 小数点前整数转换为二进制:10110000
  16. 小数点后:小数部分乘以2,取整数部分,直至乘积小数部分为0
  17. 0.0625 * 2 = 0.125 整数为0
  18. 0.125 * 2 = 0.25 整数为0
  19. 0.25* 2 = 0.50 整数为0
  20. 0.5* 2 = 1.0 整数为1,小数部分为0,结束
  21. 小数点后的小数位转换为二进制:0001
  22. 176.0625转换为二进制为:10110000.0001
  23. 2IEEE754约定小数点左边隐含有一位,通常这位数是1,所以10110000.0001=1.01100000001 * 2^7(小数点向左偏移7位);
  24. IEEE754约定单精度指数偏移量为127,所以176.0625使用IEEE754标准表示时,指数偏移量为 7+127=134 ,即:10000110
  25. IEEE754约定单精度尾数长度为23,所以176.0625使用IEEE754标准表示时,尾数为:01100000001000000000000(后面补0
  26. 176.0625>0,即为整数,所以符号位为0
  27. 3、因此:176.0625使用IEEE754规格化后的表示为:0 10000110 01100000001000000000000
  28. # Tips:以0.1解释精度误差的原因??
  29. 0.1 例解释浮点误差的原因, 0.1 转成二进制表示为 0.0001100110011001100(1100循环),1.100110011001100x2^-4,所以 E=-4+1023=1019M舍去首位的1,最终得到IEEE754表示:00111101110011001100110011001101
  30. # 在js中,为什么 x=0.1 能得到 0.1?
  31. 因为 mantissa 固定长度是52位,再加上省略的一位,最多可以表示的数是 2^53=9007199254740992,对应科学计数尾数是 9.007199254740992,由于253次方是一个16位的十进制数值,这也是JS最多能表示的精度。它的长度是 16,所以可以使用toPrecision(16)来做精度运算,超过的精度会自动做凑整处理。于是就有:
  32. 0.10000000000000000555.toPrecision(16)
  33. // 返回 0.1000000000000000,去掉末尾的零后正好为 0.1
  34. // 但你看到的 `0.1`实际上并不是`0.1`。可用更高的精度试试:
  35. 0.1.toPrecision(21) = 0.100000000000000005551
  36. # 指数位偏移的作用
  37. # 浮点数问题 0.1+0.2=0.30000000000000004?
  38. // 0.1 和 0.2 都转化成二进制后再进行运算
  39. 0.0001100110011001100110011001100110011001100110011001101 +
  40. 0.0011001100110011001100110011001100110011001100110011010 =
  41. 0.0100110011001100110011001100110011001100110011001100111
  42. // 转成十进制正好是 0.30000000000000004

  1. 所谓定点数是指数据的小数点位置是固定不变的。由于定点数的小数点位置是固定的,因此小数点“.”就不需要表示出来了。在计算机中,定点数主要分为两种:一是定点整数,即纯整数;二是定点小数,即纯小数。
  2. 假设用一个n+1位二进制来表示一个定点数x,其中一位x0用来表示数的符号位,其余n位数代表它的数值。这样,对于任意定点数x=x012 …xn,其在机器中的定点数表示如下:
  3. x0 | x1 x2 x3 x4
  4. 符号|数值
  5. 1)如果数x表示的是纯小数,那么小数点位于x0和x1之间,其数值范围为:
  6. 0<=|x|<=1-2^(-n)
  7. 2)如果数x表示的是纯整数,那么小数点位于最低位xn 的右边,其数值范围为:
  8. 0<=|x|<=2^(n+1)-1
  9. 在采用定点数表示的机器中,对于非纯整数或纯小数的数据在处理前必须先通过合适的比例因子转换成相应的纯整数或纯小数,运算结果再按比例转换回去。目前计算机中多采用定点纯整数表示,因此将定点数表示的运算简称为整数运算

  1. # 数字的进制
  2. 使用字面量(literal)直接表示一个数值时,JavaScript 对整数提供四种进制的表示方法:十进制、十六进制、八进制、二进制。
  3. 十进制:没有前导0的数值。
  4. 八进制:有前缀0o0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。
  5. 十六进制:有前缀0x0X的数值。
  6. 二进制:有前缀0b0B的数值。
  7. Tips:默认认情况下,JavaScript内部会自动将八进制、十六进制、二进制转为十进制。
  8. ## 特殊数值
  9. 1JavaScript 内部实际上存在20:一个是+0,一个是-0,区别就是64位浮点数表示法的符号位不同。它们是等价的。
  10. 2NaN JavaScript 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。(NaN不等于任何值,包括它本身)
  11. 3Infinity表示“无穷”,用来表示两种场景。一种是一个正的数值太大,或一个负的数值太小,无法表示;另一种是非0数值除以0,得到Infinity
  12. ## 一些函数
  13. isFinite方法返回一个布尔值,表示某个值是否为正常的数值。
  14. isNaN方法可以用来判断一个值是否为NaN
  15. parseFloat方法用于将一个字符串转为浮点数。
  16. parseInt方法用于将字符串转为整数。//进制转换
  17. toPrecision 是处理精度,精度是从左至右第一个不为0的数开始数起。
  18. toFixed 是小数点后指定位数取整,从小数点开始数起。
  19. # Tips:大数危机和精度
  20. 1 JavaScript 能够表示的数值范围为2^10242^(-1023)(开区间),超出这个范围的数无法表示。(特殊值02047被保留的缘故,全0和全1IEEE754中)
  21. 如果一个数大于等于21024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回Infinity
  22. Math.pow(2, 1024) // Infinity
  23. 如果一个数小于等于2的-1075次方(指数部分最小值-1023,再加上小数部分的52位),那么就会发生为“负向溢出”,即 JavaScript 无法表示这么小的数,这时会直接返回0。(有非规格化值)
  24. Math.pow(2, -1075) // 0
  25. 2、精度最多只能到53个二进制位,这意味着,绝对值小于等于253次方的整数,即-2^532^53,都可以精确表示。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注