美文网首页
JavaScript中的数值

JavaScript中的数值

作者: 程序员之家 | 来源:发表于2023-08-20 12:07 被阅读0次

    JavaScript中的主要数值类型是Number类型,用于表示整数和近似的实数。JavaScript采用了由IEEE 754标准定义的64位浮点格式来表示数值。这意味着JavaScript可以表示最大整数±1.797 693 134 862 315 7 × 10^308和最小整数±5 × 10^-324。

    JavaScript中的这种数值格式允许我们准确表示介于-9,007,199,254,740,992(-2^53)和9,007,199,254,740,992(2^53)之间的所有整数。如果您的值超出此范围,可能会在最低有效位处丧失一些精度。

    当一个数值直接出现在JavaScript程序中时,它被称为“数值字面量”。请注意,任何数值字面量都可以在前面加上减号(-)以使值为负。

    1. 整数字面量.

    在JavaScript程序中,十进制整数可以直接写为数字序列。例如:

    0

    3

    10000000

    除了十进制整数字面量,JavaScript还支持十六进制(基数16)的值。十六进制字面量以0x或0X开头,后面跟着十六进制数字字符串。十六进制数字由数字0到9和字母a(或A)到f(或F)组成,其中a到f代表10到15。以下是十六进制整数字面量的示例:

    //=> 255:(15*16 + 15)

    0xff

    //=> 195939070

    0xBADCAFE

    在ES6及更高版本中,您还可以使用前缀0b和0o(或0B和0O)来表示二进制(基数2)或八进制(基数8)的整数:

    //=> 21:(1*16 + 0*8 + 1*4 + 0*2 + 1*1)

    0b10101

    //=> 255:(3*64 + 7*8 + 7*1)

    0o377

    (程序员的软技能:ke.qq.com/course/6034346)

    2. 浮点数字面量.

    浮点数字面量可以包含小数点,并遵循实数的传统语法。实数由数字的整数部分、小数点和数字的小数部分组成。

    浮点数字面量还可以使用指数表示法,其中实数后跟字母e(或E),一个可选的加号或减号,以及一个整数指数。这种表示法表示实数乘以10的指数次幂。

    更简洁的语法形式为:

    [digits][.digits][(E|e)[(+|-)]digits]

    例如:

    3.14

    2345.6789

    .333333333333333333

    //6.02 x 10^23

    6.02e23

    //1.4738223 x 10^-32

    1.4738223E-32

    您可以使用下划线来分隔数值字面量的各个部分,这是一种已进入标准化后期并受到所有主要浏览器和Node实现支持的功能:

    // 使用下划线作为千分位分隔符

    let billion = 1_000_000_000;

    // 使用下划线作为字节分隔符

    let bytes = 0x89_AB_CD_EF;

    // 使用下划线作为半字节分隔符

    let bits = 0b0001_1101_0111;

    // 也可以用于小数部分

    let fraction = 0.123_456_789;

    (程序员的软技能:ke.qq.com/course/6034346)

    3. JavaScript中的算术运算。

    JavaScript程序使用语言提供的算术运算符来操作数值。这些运算符包括加法+、减法-、乘法*、除法/和取模(除法后的余数)%。ES2016引入了指数运算符**。

    除了这些基本的算术运算符,JavaScript还通过Math对象提供了一组函数和常量,以支持更复杂的数学计算:

    // => 9007199254740992:2的53次方

    Math.pow(2, 53)

    // => 1.0:四舍五入到最近的整数

    Math.round(0.6)

    // => 1.0:向上取整到最近的整数

    Math.ceil(0.6)

    // => 0.0:向下取整到最近的整数

    Math.floor(0.6)

    // => 5:绝对值

    Math.abs(-5)

    // 返回提供参数的最大值

    Math.max(x, y, z)

    // 返回提供参数的最小值

    Math.min(x, y, z)

    // 伪随机数x,其中0 <= x < 1.0

    Math.random()

    // π:代表数学常数π的常量

    Math.PI

    // e:代表自然对数的底数e的常量

    Math.E

    // => 3**0.5:3的平方根

    Math.sqrt(3)

    // => 3**(1/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

    // Math.E的立方

    Math.exp(3)

    ES6在Math对象上引入了一组新的函数:

    // => 3:立方根

    Math.cbrt(27)

    // => 5:一组参数平方和的平方根

    Math.hypot(3, 4)

    // => 2:以10为底的对数

    Math.log10(100)

    // => 10:以2为底的对数

    Math.log2(1024)

    // (1+x)的自然对数:对于非常小的x很精确

    Math.log1p(x)

    // Math.exp(x) - 1;Math.log1p()的反函数

    Math.expm1(x)

    // 根据参数的符号返回-1、0或1

    Math.sign(x)

    // => 6:优化的32位整数乘法

    Math.imul(2, 3)

    // => 28:32位二进制表示中前导零位的数量

    Math.clz32(0xf)

    // => 3:去掉小数部分以得到整数

    Math.trunc(3.9)

    // 四舍五入到最近的32位浮点值

    Math.fround(x)

    // 双曲正弦,还有Math.cosh()和Math.tanh()

    Math.sinh(x)

    // 双曲反正弦,还有Math.acosh()和Math.atanh()

    Math.asinh(x)

    在JavaScript中,算术不会在遇到溢出、下溢或除以零时抛出错误。当数值操作的结果超出可表示范围(溢出)时,结果是特殊的无限值Infinity。类似地,当负数的绝对值超出负数的可表示范围(下溢)时,结果为负无穷-Infinity。这两个无限值的行为符合预期:涉及加法、减法、乘法或除法的任何算术运算都会导致无限值(尽管符号可能会改变)。

    当数值操作的结果接近零但仍大于最小可表示数时,发生下溢。在这种情况下,JavaScript返回0。如果下溢发生在倒数的情况下,JavaScript返回一个称为“负零”的特殊值。这个值与普通零几乎无法区分,对于JavaScript程序员来说很少会引起关注。

    在JavaScript中,除以零不是错误;它只会导致无限或负无穷。然而,有一个例外:将0除以0会得到一个称为“非数”(NaN)的特殊值。此外,类似无限除以无限、负数的平方根或在算术运算中使用NaN作为操作数等操作都会产生NaN作为结果。

    JavaScript预定义了全局常量Infinity和NaN,分别对应正无穷大和非数。这些值也可以通过Number对象的属性访问:

    // 由于过大无法表示,得到正无穷大

    Infinity

    // 与上面相同

    Number.POSITIVE_INFINITY

    // => Infinity

    1 / 0

    // => Infinity;溢出

    Number.MAX_VALUE * 2

    // 由于过大无法表示为负数,得到负无穷大

    -Infinity

    // 与上面相同

    Number.NEGATIVE_INFINITY

    // => -Infinity

    -1 / 0

    // => -Infinity

    -Number.MAX_VALUE * 2

    // NaN:非数

    NaN

    // 与上面相同,不同的语法

    Number.NaN

    // => NaN

    0 / 0

    // => NaN

    Infinity / Infinity

    // => 0:下溢

    Number.MIN_VALUE / 2

    // => -0:负零

    -Number.MIN_VALUE / 2

    // => -0:也是负零

    -1 / Infinity

    //

    -0

    ES6在Number对象上引入了以下属性:

    // 与全局parseInt()函数相同

    Number.parseInt()

    // 与全局parseFloat()函数相同

    Number.parseFloat()

    // 检查x是否为NaN

    Number.isNaN(x)

    // 检查x是否为有限数

    Number.isFinite(x)

    // 检查x是否为整数

    Number.isInteger(x)

    //

    Number.isSafeInteger(x)

    // => -(2**53 - 1)

    Number.MIN_SAFE_INTEGER

    // => 2**53 - 1

    Number.MAX_SAFE_INTEGER

    // => 2**-52:两个可表示数之间的最小差值

    Number.EPSILON

    在JavaScript中,NaN具有一种不寻常的特性:它既不等于任何值,也不等于自身。这意味着您不能通过使用x === NaN比较来确定变量x是否为NaN。相反,您必须使用x != x或Number.isNaN(x)来测试NaN。这两个表达式只在x与全局常量NaN具有相同值时才返回true。

    全局函数isNaN()与Number.isNaN()类似。当参数为NaN或参数为不能转换为数字的非数值时,它返回true。相关的函数Number.isFinite()在参数不是NaN、Infinity或-Infinity时返回true。全局函数isFinite()在参数为有限数或可转换为有限数的值时返回true。

    负零具有稍微不寻常的行为。它被认为等于正零(即使在JavaScript中使用严格相等比较),这意味着除了作为除数的角色外,很难区分这两个值:

    // 普通零

    let zero = 0;

    // 负零

    let negz = -0;

    // => true:零等于负零

    zero === negz

    // => false:Infinity不等于负无穷

    1 / zero === 1 / negz

    (程序员的软技能:ke.qq.com/course/6034346)

    4. 二进制浮点数和舍入误差。

    实数是无限多的,但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,但不能完全表示它。这可能会导致问题,如以下代码所示:

    // 30美分减去20美分

    let x = 0.3 - 0.2;

    // 20美分减去10美分

    let y = 0.2 - 0.1;

    // => false:这两个值不相等!

    x === y

    // => false:.3 - .2不等于.1

    x === 0.1

    // => true:.2 - .1等于.1

    y === 0.1

    由于舍入误差,近似值0.3和0.2之间的差异不等于近似值0.2和0.1之间的差异。这不是JavaScript特定的问题;这是所有使用二进制浮点数的编程语言的常见问题。还要注意,上述代码中的x和y的值非常接近,它们非常接近正确的值。计算出的值对于大多数目的来说都是完全合适的,但不建议尝试比较它们的精确相等性。

    如果近似浮点值在您的程序中造成问题,您可以考虑使用等价的整数。例如,在处理与货币相关的计算时,您可以使用以分为单位的整数表示,而不是以美元的一部分为单位的分数。

    (程序员的软技能:ke.qq.com/course/6034346)

    5. 用BigInt表示任意精度整数。

    在ES2020中,JavaScript引入了一种新的数字类型,称为BigInt。截至2020年初,Chrome、Firefox、Edge和Node.js已经实现了这种类型,Safari也在进行相关工作。正如名称所示,BigInt值是整数。添加此类型的主要动机是为了表示64位整数,这对于与许多其他语言和API的兼容性至关重要。然而,BigInt值可以具有数千甚至数百万位的数字,以满足大数值的需求(尽管BigInt实现不适合用于加密,因为它们不考虑防御定时攻击)。

    BigInt字面量由一系列数字后跟小写字母"n"组成。默认情况下,基数为10,但您可以使用前缀0b、0o和0x分别表示二进制、八进制和十六进制的BigInt:

    // 一个不太大的BigInt字面量

    1234n

    // 二进制BigInt

    0b111111n

    // 八进制BigInt

    0o7777n

    // => 2n ** 63n:一个64位整数

    0x8000000000000000n

    您可以使用BigInt()函数将常规JavaScript数字或字符串转换为BigInt值:

    // => 9007199254740991n

    BigInt(Number.MAX_SAFE_INTEGER)

    // 一个由1后面跟100个零组成的数字

    let string = "1" + "0".repeat(100);

    // => 10n ** 100n:一个天文数字

    BigInt(string)

    与BigInt值的算术操作类似于常规JavaScript数字操作,除法除去余数并朝向零四舍五入:

    // => 3000n

    1000n + 2000n

    // => 1000n

    3000n - 2000n

    // => 6000000n

    2000n * 3000n

    // => 3n:商为3

    3000n / 997n

    // => 9n:余数为9

    3000n % 997n

    // 一个有39457位的梅森素数

    (2n ** 131071n) - 1n

    尽管标准的+、-、*、/、%和**运算符适用于BigInt,但您不能将BigInt操作数与常规数字操作数混合使用。乍看起来,这个规则可能有点奇怪,但实际上是合理的。如果一个数值类型比另一个更通用,那么定义混合操作数计算并返回更通用的类型是很容易的。然而,在这种情况下,这两种类型都不比另一种更通用:BigInt可以表示非常大的值,使其在常规数值类型之间更通用。但是BigInt只能表示整数,这使得常规JavaScript数值类型在这个方面更通用。这种困境无法解决,因此在使用算术运算符时,JavaScript简单地禁止混合使用这两种操作数类型。

    另一方面,比较运算符允许混合操作数类型:

    // => true

    1 < 2n

    // => true

    2 > 1n

    // => true

    0 == 0n

    // => false:===还检查类型相等性

    0 === 0n

    位运算符通常可以与BigInt操作数一起使用。然而,Math对象的函数中没有一个接受BigInt操作数。

    (程序员的软技能:ke.qq.com/course/6034346)

    6. 日期和时间。

    JavaScript提供了一个简单的Date类,用于表示和操作与日期和时间有关的数据。JavaScript的Date是一个对象,但它也具有一个数值表示,称为时间戳,它是自1970年1月1日以来的毫秒数:

    // 当前时间的时间戳(数值)

    let timestamp = Date.now();

    // 当前时间的Date对象

    let now = new Date();

    // 转换为毫秒时间戳

    let ms = now.getTime();

    // 转换为ISO格式的字符串

    let iso = now.toISOString();

    (程序员的软技能:ke.qq.com/course/6034346)

    相关文章

      网友评论

          本文标题:JavaScript中的数值

          本文链接:https://www.haomeiwen.com/subject/fxpsmdtx.html