每一个Javascript程序员都应该了解的浮点知识
来源:互联网 发布:阿里云实例重装系统 编辑:程序博客网 时间:2024/05/18 14:12
p
跟着D,D1.D2D3D4...Dp叫有效数字或尾数。p
是有效数字的数量,通常叫做精度。x
跟随在尾数后面,它是表达式的一部分(在这篇文章中乘法符号用*表示)。基数后面紧随着的是指数。指数可以是正数或负数。11.00100100 001111...
.。假设这个数用16位方式去表示,这个数字在机器中会是这样:11001001000011111。现在问题是:小数点去哪了?这个尽然不包含指数(我们假定这是基于二进制的)。101
,代替上面的11,需要多一个位字段。当然我们可以指定第一个N位的字段属于整数部分(例如:小数点左边的部分),剩下的属于小数部分,不过这个知识点属于另一篇主题为定点数的文章。可能要注意到浮点数机器表达式和我们写的表达式有一点点区别——这是惯例。在64位可用空间中,有一位用来标记——不管这个数是正数还是负数。11位用来放指数——这个允记的最大指数是1024。剩下的52位分配给尾数。也许你一直奇怪在javascript中怎么会有 +0
和 -0
,用符号位解释——所有的数字在Javascript中都有符号位。 Infinity
和 NaN
也是用浮点表达式编码的——带有一个 2047
的特殊指数。如果尾数是 0
,它是一个正整数或负整数。如果不是,那么它是 NaN
。
舍入误差
上面浮点表达式已经介绍完毕,现在进入一个更棘手的问题——舍入误差。这是所有程序员编写浮点数相关代码时的痛苦来源,Javascript更是如此,因为在Javascript中只能用数字格式表示浮点数。
上面已经提到分数不能完全用十进制表示,例如:1/3。这个问题普遍存在。例如,在二进制中,1/10不能完全表示出来,它可以表示为 0.00110011001100110011...
。注意到这个0011
是无限循环的。这种特殊情况是因为发生了舍入误差。
首先,初步了解一下舍入误差。来看这个非常著名的无理数,派: 3.141592653589793...
。非常多人记住了5个数(3.1415),这就是舍入的很好解释,下面我们会用到这个解释。舍入误差可以这样计算:
(R - A) / Bp-1
这里面 R
是取整数, A
是实数。 B
和我们先前提到的 p
相同,它是表示精确度。所以这个难忘的派有了一个舍入误差: 0.00009265...
。
这个问题似乎不严重,让我们试试二进制数。用分数1/10。基于10进制,它写成0.1。用二进制它是:0.0011001100110011...
。假定我们舍入到5个尾数,它是 0.0001
。但是 0.0001
在二进制中实际上是1/16(或者0.0625)!这意味这有一个0.0375的舍入误差,这个误差相当大。想象一下做一个基本的数学运算0.1+0.2,结果确是0.2625!
幸运的是,按照浮点表示法的规定,ECMAScrip指定了52位尾数,所以这个舍入误差非常小——这个规定特别详细说明了大部分数字的预计舍入误差。因为随着时间的推移执行浮点运算操作引发的错误会越来越多,IEEE 754标准也为数学运算指定了算法。
除了这些还有一点要注意。结合性的算法在处理浮点时不能保证正确,即使在高精度情况下。我的意思是 ((x + y) + a + b)
不一定等于 ((x + y) + (a + b))
。
toPrecision()
和 toFixed()
方法。任何想去使用它的人请注意——这些方法返回字符串格式。你可以看看下面的代码:function foo(x, y) { return x.toPrecision() + y.toPrecision()}> foo(0.1, 0.2)"0.10.2"
内置函数 toPrecision()
和 toFixed()
方法目的是为了显示。小心使用。
- 每一个Javascript程序员都应该了解的浮点知识
- 每一个JavaScript开发者应该了解的浮点知识
- javascript的程序员都应该了解的
- 每个程序员都应该了解的内存知识
- 每个程序员都应该了解的内存知识【第一部分】
- 每个程序员都应该了解的内存知识-1
- 每个程序员都应该了解的内存知识
- 每个程序员都应该了解的内存知识
- 每个程序员都应该了解的内存知识【第一部分】
- 每个程序员都应该了解的“虚拟内存”知识
- 每个程序员都应该了解的“虚拟内存”知识
- 每个程序员都应该了解的内存知识 part1
- 每个程序员都应该了解的内存知识【第一部分】
- 每个程序员都应该了解的“虚拟内存”知识
- 每个程序员都应该了解的“虚拟内存”知识
- 每个程序员都应该了解的内存知识
- 每个程序员都应该了解的内存知识(一)
- 每个程序员都应该了解的内存知识(二)
- C++中程序化操作虚函数列表实验
- android 如何设置checkbox、edittext点击前后不同样式
- SSH框架总结(框架分析+环境搭建+实例源码下载)--这个很值得一读~!
- 互联网通信应用定义
- 【c++】PAT (Advanced Level)1023. Have Fun with Numbers (20)
- 每一个Javascript程序员都应该了解的浮点知识
- 日期结构体
- 成为一个 PHP 专家:缺失的环节
- VisionMobile:2014年Q1移动开发者经济报告(五)2.2、地区前景
- zoj 2301 Color the Ball(区间染色,线段树+离散化)
- java各种框架的比较,分析
- 键盘上的英文符号
- 【Mysql】mysql表分区3 —Hash分区
- 黑客常用WinAPI函数整理