1.2 数字
不出所料,数字类型的值是数值。在JavaScript程序中,它们用如下格式编写:
在程序中使用它,将使得计算机内存中存在数字13的二进制位模式。
JavaScript使用固定长度的二进制位(64位)来存储单个数值。使用64位可以做出的模式只有那么多,这意味着它可以表示的不同数字的数量是有限的。使用N个十进制数字,你可以表示10N个数字。同样,给定64个二进制数字,你可以表示264个不同的数字,大约是18百亿亿(18之后有18个零)。
过去的计算机存储器比现在小得多,人们倾向于使用8个或16个二进制位的组来表示它们的数字。这么小的数字很容易意外地溢出——最终得到一个在给定位数中放不下的数字。如今即使是口袋电脑也有足够的内存,所以你可以自由使用64位块,而你只有在处理真正的天文数字时才需要担心溢出。
但是,并非所有小于18百亿亿的数字都适合用JavaScript编码。由于这些二进制位也存储负数,因此要用一个二进制位表示数字的符号。更大的问题是还必须表示非整数。为此,还要用一些位来存储小数点位置。实际可以存储的最大整数更多的是在9千万亿(9后面15个零)的范围内——这仍然是非常大的。
小数是用带小数点的数来表示的。
对于非常大或非常小的数字,你也可以使用科学记数法,通过添加e(表示指数),后面跟着整数的指数来实现。
即2.998×108=299800000。
计算小于上述9千万亿的整数(也称为整型数)可以保证始终精确。遗憾的是,带小数的计算通常不精确。正如π(pi)不能用有限数量的十进制数精确表示一样,当只有64位可用于存储它们时,许多数字会丢失一些精度。这是一种耻辱,但只有在特定情况下才会引起实际问题。重要的是要注意这件事并将小数数字视为近似值,而不是精确值。
1.2.1 算术
与数字有关的主要是算术。加法或乘法等算术运算需要两个数值,并从中产生一个新数值。这是它们在JavaScript中的样子:
+和*符号称为运算符。第一个代表加法,第二个代表乘法。将运算符放在两个值之间将对这些值进行运算并生成新值。
但这个例子的意思是“把4和100相加,然后将结果乘以11”,还是在加法之前完成乘法呢?正如你可能已经猜到的那样,乘法首先执行。但是在数学中,你可以通过把加法包含在括号中来改变这一点。
对于减法,有-运算符,还可以使用/运算符进行除法。
当多个运算符一起出现而没有括号时,它们的运算顺序取决于运算符的优先级。本例显示乘法在加法之前执行。运算符/与*具有相同的优先级。+和-也有相同的优先级。当具有相同优先级的多个运算符彼此相邻时,应从左到右运算,如在1-2+1中,运算顺序是(1-2)+1。
不需要担心记不住这些优先规则。如果你不确定,添加括号即可。
还有一个算术运算符,你可能无法立即认出来。%符号用于表示取余数操作。X%Y是取X除以Y的余数。例如,314%100得到14,144%12得到0。余数运算符的优先级与乘法和除法的优先级相同。还经常会将此运算符称为取模运算符。
1.2.2 特殊数字
JavaScript中有三个特殊值,它们被视为数字,但其行为不像普通数字那样。
前两个是Infinity和-Infinity,代表正无穷大和负无穷大。Infinity -1仍然是Infinity,等等。但是,不要过分信任基于无穷大的计算。它不是像数学上的那样,它会很快导致下一个特殊值:NaN。
NaN代表“不是数字”,即使它是数字类型的值。例如,当你尝试计算0/0(零除以零)、Infinity - Infinity或任何其他不产生有意义结果的数字运算时,你都会得到这个结果。