当一个数字直接出现在JavaScript程序中,称之为数字直接量。
JavaScript支持多种格式的数字直接量,在任何数字直接量前添加符号(-)可以得到他的负值。但负号是一元求反运算符,并不是数字直接量语法的组成部分。
整型直接量
在JavaScript程序中,用一个数字序列表示一个十进制整数。
除了十进制的整型直接量,JavaScript同样能识别十六进制的值。所谓十六进制的直接量是以“0x”或“0X”为前缀,其后跟随十六进制数串的直接量。十六进制值是0~9之间的数字和啊a(A) ~ f(F)之间的字母构成,a ~ f的字母对应的表示数字10 ~ 15.
// 15 * 16 + 15 == 255(十进制)
0xff
0xCAFE911
尽管ECNASciprt标准不支持八进制直接量,但JavaScript的某些实现可以允许采用八进制(基数为8)形式表示整数。八进制直接量以数字0开始,其后跟随一个有0 ~7 (包括 0 ~ 7)之间的数字组成的序列
// 3 * 64 + 7 * 8 + 7 = 255(十进制)
0377
由于某些JavaScript的实现支持八进制直接量,而有些不支持,因此最好不要使用以0为前缀的整型直接量,毕竟我们也无法得知JavaScript的实现是否支持八进制的解析。在ECMAScript 6 的严格模式下,八进制直接量是明令禁止的
浮点型直接量
浮点型直接量可以包含小数点,它们采用的是传统的实数写法。一个实数由整数部分、小数点和小数部分组成。
此外,还可以使用指数记数法表示浮点型直接量,即在实数跟字母e或E,后面再跟正负号,其后再加一个整型的指数。这种记数方法表示的数值,是由前面的实数乘以10的指数次幂。
// 使用简洁的语法表示
[digits][.digits][(E|e)[+|-]digits]
// 例如
3.14
2345.78g
.33333333333
6.02e23 // 6.02* 10^33
JavaScript中的算术运算
JavaScript程序是使用语言本身提供的算术运算符来进行数字运算的。这些运算符包括加“+”、减”-“ 、 乘 ”*“ 、除”/“和求余(%)
除了基本的运算符外。JavaScript还支持更加复杂的算术运算,这些复杂运算通过作为Math对象的属性定义和常量来实现:
//9007199254740992:2的53次幂
Math.pow(2,53)
// 四舍五入
Math.round(.6)
// 向上取整
Math.ceil(.6)
// 向下取整
Math.floor(.6)
// 求绝对值
Math.abs(-5)
// 返回最大值
Math.max(x,y,z)
// 返回最小值
Math.min(x,y,z)
// 生成一个大于等于0小于1的伪随机数
Math.random()
// Π 圆周率
Math.PI
// 自然对数的底数
Math.E
// 3的平方根
Math.sqrt(3)
// 3 的立方根
Math.pow(3,1/3)
// 三角函数 还有Math.cos, Math.atan等
Math.sin(0)
// 10的自然对数
Math.log(10)
// 以10为底100的对数
Math.log(100)/Math.LN10
// 以2为底512的对数
Math.log(512)/Math.LN2
// e的三次幂
Math.exp(3)
JavaScript中的算术运算在溢出(overflow)、下溢(underflow)或被零整除是不会报错。当数字运算结果超过JavaScript所能表示的数字上限(溢出),结果为一个特殊的无穷大(infinity)值,在JavaScript中以Infinity表示。同样的,当负数的值超过了JavaScript所能表示的负数范围,结果为负无穷大,在JavaScript中以-Infinity表示。无穷大值的行为特性和我们所期望的是一致的,基于它们的加、减、乘和除运算结果还是无穷大值(保留正负号)
下溢(underflow)是当运算结果无限接近于零并将JavaScript能表示的最小值还小的时候发生的一种情形。这种情况下,JavaScript将会返回0.当一个负数发生下溢时,JavaScript返回一个特殊的值’零负‘。这个值(零负)几乎和正常的零完全一样。
被零整除在JavaScript并不报错,它只是简单的返回无穷大(Infinity)或负无穷大(-Infinity)。但有一个例外,零除以零时没有意义的,这种整除运算结果也是以一个非数字(not-a-number)值,用NaN表示。无穷大除以无穷大、给任意负数作开方运算或者算术运算符与不是数字或者无法转换为数字的操作数一起使用时都将返回NaN。
JavaScript预定义了全局变量Infinity和NaN,用来表示正无穷大和非数字值。
JavaScript中的非数字值有一点特殊,它和任何值都不相等,包括自身。没有办法通过x==NaN来判断变量x是否是NaN。相反,应当使用 x!=x 来判断,当且仅当x为NaN的时候,表达式的结果才为true。函数isNaN() 的作用于此类型,如果参数是NaN或者是一个非数字值(字符串,对象),则返回true。JavaScript中有一个类似的函数isFinite(),在参数不是NaN、Infinity或者-Infinity的时候返回true。
二进制浮点数和四舍五入错误
实数有无数个,但JavaScript通过浮点数的形式只能表示其中有限的个数(确切地说是18 437 736 874 454 810 627个)。也就是说,在JavaScript中使用实数的时候,常常只是真实值的以恶搞近似表示。
JavaScript采用了IEEE-754 浮点数表示法(现代编程语言大部分在用),这是一种二进制表示法,可以精确的表示分数,比如1/2、1/8和1/1024. 遗憾的是,我们常用的分数都是十进制分数1/10、1/100等。二进制浮点数表示法并不能精确地表示类似0.1这样简单的数字。
JavaScript中的数字具有足够的精确,并可以及其近似于0.1。但事实是,数字不能精确表述的确带来的一些问题
var x = .3 - .2
var y = .2- .1
x == y // fales
x == .1 // false
y == .1 // false
由于舍入误差,0.3和0.2之间的近似差值实际上并不等于0.2和0.1之间的近似差值。在任何使用二进制浮点数的编程语言中都会有这个问题。同样注意的是,上述代码中x,y的值非常接近彼此和最终的正确值。这种计算结果可以胜任大多数的计算任务,这个问题也只有在比较两个值是否相等的时候才出现。
在JavaScript的真实运行环境中,0.3-0.2 = 0.09999999999999998