本章是数字类型的进阶讲解,有关数字类型的初步介绍请看 Number类型章节。

数字的编写

下划线

数字中的下划线会被忽略,这有助于我们书写数字的正确性。比如西方常用的千位分割符就可以用下划线替代。

$$jsdemo$$
$$edit$$
let n = 1000000 // 一百万
let n2 = 1_000_000 // 一百万,用 _ 代替千位分隔符

alert(n) // 1000000
alert(n2) // 1000000
alert(n === n2) // true

科学记数法

数值的表示中也可以使用科学记数法, e 代表 10 的幂。

$$jsdemo$$
$$edit$$
let n = 10000 // 一万
let n2 = 1e4 // 一万,用科学计数法

alert(n) // 10000
alert(n2) // 10000
alert(n === n2) // true

let n3 = 0.012 // 0.012
let n4 = 12e-3 // 0.012,用科学计数法

alert(n3) // 0.012
alert(n4) // 0.012
alert(n3 === n4) // true

进制

默认的数字是十进制 ,意味着逢十进一,每位上取值是 0 ~ 9 。除此之外常用的还有十六进制八进制二进制

  • 十六进制:逢十六进一,每位上取值是 0 ~ f
  • 八进制:逢八进一,每位上取值是 0 ~ 7
  • 二进制:逢二进一,每位上取值是 0 ~ 1

$$tip

在线进度转换工具

$$

$$jsdemo$$
$$edit$$
let n = 0xff // 十六进制 255
let n2 = 0o377 // 八进制 255
let n3 = 0b11111111 // 二进制 255
alert(n === n2)
alert(n2 === n3)

toString(base)

虽然以其他进制保存了数字,但其值在显示的时候仍是以十进制显示。

$$jsdemo$$
$$edit$$
let n = 0xff // 十六进制 255
alert(n) // 255

如果我们要以其他进制显示,就要手动调用 toString(base) 方法。 toString 可以将一个数字类型转换为字符串类型, base 参数表示进制,默认值为十进制。

$$jsdemo$$
$$edit$$
let n = 0xff // 十六进制 255

alert(typeof n) // number
alert(typeof n.toString()) // string

alert(n.toString(16)) // ff
alert(n.toString(2)) // 11111111

$$tip

使用 toString(base) 的场所是一些需要特定十六进制字符的场所,比如颜色取值。

$$

toFixed(digits)

toFixed(digits) 方法同样可以将一个数字转成字符串,但同样还能以四舍五入的方式决定保留固定的小数位数。

$$jsdemo$$
$$edit$$
let n = 123.45
alert(typeof n.toFixed()) // string
alert(n.toFixed()) // 123
alert(n.toFixed(1)) // 123.5
alert(n.toFixed(4)) // 123.4500

toPrecision(precision)

toPrecision(precision) 同样是将一个数字转成字符串,不同的是四舍五入到指定的精度。

$$jsdemo$$
$$edit$$
let n = 123.45
alert(typeof n.toPrecision()) // string
alert(n.toPrecision()) // 123.45
alert(n.toPrecision(1)) // 1e+2,也就是 100
alert(n.toPrecision(4)) // 123.5

字符串转数字

字符串转数字一般有两种方法,使用 Number()parseInt

对于已经以特定标识开头的不同进制字符串, Number()parseInt() 都能做到很好的转换。

$$jsdemo$$
$$edit$$
let n = Number("0xff") // 255
let n2 = parseInt("0xff") // 255
alert(n) // 255
alert(typeof n) // number
alert(n === n2) // true

但如果没以特定标识开头的字符串,就必须用 parseInt() 转换,在第二个参数中标明进制。

$$jsdemo$$
$$edit$$
let n = parseInt("ff", 16) // 按16进制转换
alert(n) // 255

$$warning

parseInt() 只能进行整数的转换。

$$

parseFloat

parseFloat() 可以将一个浮点数字符串转换为数字类型。

$$jsdemo$$
$$edit$$
let n = parseFloat("2.22")
alert(n) // 2.22
alert(typeof n) // number

$$tip

以上方法都来自 Number 类型的自带方法,有关 Number 类型所有属性与方法的完整介绍请看 Number - MDN

$$

数学运算库

Math 是一个内置的对象,包含了一些数学运算的属性或方法,以下章节会介绍一些常用的属性或方法,详情可以参考 Math - MDN

$$warning

Math 只用用于 Number 类型,不支持 BigInt 类型。

$$

常用属性

Math.E // 欧拉常数,约等于 2.718。
Math.LN2 // 2 的自然对数,约等于 0.693。
Math.LN10 // 10 的自然对数,约等于 2.303。
Math.LOG2E // 以 2 为底的 E 的对数,约等于 1.443。
Math.LOG10E // 以 10 为底的 E 的对数,约等于 0.434。
Math.PI // 圆周率,一个圆的周长和直径之比,约等于 3.14159。
Math.SQRT1_2 // 2 的平方根的倒数,约等于 0.707。
Math.PI // 圆周率,一个圆的周长和直径之比,约等于 3.14159。
Math.SQRT2 // 2 的平方根,约等于 1.414。

常用方法

绝对数

Math.abs(x) 可以返回一个数的绝对数。

Math.abs(10) // 10
Math.abs(-10) // 10

四舍五入

Math.round(x) 返回一个数四舍五入后的整数。

Math.round(2.5) // 3
Math.round(2.4) // 2

向上取整

Math.ceil(x) 返回大于一个数的最小整数,即一个数向上取整的结果。

Math.ceil(2.1) // 3
Math.ceil(2.4) // 3

向下取整

Math.floor(x) 返回小于一个数的最大整数,即一个数向下取整的结果。

Math.floor(2.6) // 2
Math.floor(2.9) // 2

舍去小数

Math.trunc(x) 方法会舍去数字的小数部分,只保留整数,注意与 Math.floor(x) 向下取整的区别。

Math.trunc(1.2) // 1
Math.trunc(-1.2) // -1

Math.floor(1.2) // 1
Math.floor(-1.2) // -2

随机数

Math.random() 返回一个 在 0(包括)至 1(不包括)之间的浮点数。

$$jsdemo$$
$$edit$$
alert(Math.random()) // 每次结果都不一样

实例:返回区间内的随机数

Math.random() 只能返回 0 和 1 之间的数,以下实现了一个返回 a(包含)、b(不包含)区间内的数。

$$jsdemo$$
$$edit$$
function ranIn(a, b) {
    let diff = b - a // 先求出他们的差值
    let result = diff * Math.random() // 再与随机数相乘
    return result + a // 最后加上 a 即可
}
// 返回 2(包含)、6(不包含)之间的任意数
alert(ranIn(2, 6))

精度损失

精度损失说是一些小数运算后与实际结果出现偏差的情况。

$$jsdemo$$
$$edit$$
alert(0.1 + 0.2 == 0.3) // false
alert(0.1 + 0.2) // 0.30000000000000004

这是因为小数在计算机中是以二进制进行保存与运算,当一些小数用二进制表示时是一个无限的二进制,就会损失一些精度。

解决思路

  • 能以整数运算的以整数运算,比如价格以分作为单位,只有在显示时将其除以 100 后显示。
  • 对于精度要求不高的场景使用 toFixed 保留对应精度,应注意此时返回的是字符串。
  • 引入第三方类型库,比如 decimal.jsbignumber.jsbig.js 都是一些很优秀的高精度计算库。

练习

  1. 实现一个函数 ranInt 返回两个参数 a、b 间的随机整数,包含 a、b。
function ranInt(a, b) {
    // 补充完成
}
alert(ranInt(4, 9)) // 随机整数

$$demo

<body>

<button onclick="show()">演示实例</button>

</body>

<script>

function show() {

function ranInt(a, b) {

let diff = b - a

diff = diff * Math.random()

let result = a + diff

result = Math.round(result)

return result

}

alert(ranInt(4, 9)) // 随机整数

}

</script>

$$

$$answer

$$jsdemo$$
$$edit$$
function ranInt(a, b) {
    let diff = b - a
    diff = diff * Math.random()

    let result = a + diff
    result = Math.round(result)

    return result
}
alert(ranInt(4, 9)) // 随机整数

$$

  1. 结合餐饮数据完成以下餐饮建议程序,注意点 5 次以上的结果。
let lunches = [
    "牛肉面",
    "盖浇饭",
    "蛋炒饭",
    "烧饼",
    "黄焖鸡",
    "麻辣烫",
    "烤鸭",
]

$$demo <div class="container"> <h1 class="tip">让我来决定你午餐吃啥~</h1> <!-- <h1 class="tip">今天午餐吃:<span class="lunch">牛肉面</span></h1> --> <button class="btn" onclick="ranLunch()">随机大餐</button> </div>

<style> .container { text-align: center; }

.lunch {
    color: teal;
    font-size: 1.2em;
}

</style> <script> let lunches = [ "牛肉面", "盖浇饭", "蛋炒饭", "烧饼", "黄焖鸡", "麻辣烫", "烤鸭", ]

function ranChoose(array) {
    // 从数组中随机选择一个元素

    let idx = array.length * Math.random()

    idx = Math.floor(idx)

    return array[idx]
}

let counter = 0

function ranLunch() {
    // 随机大餐

    counter++
    if (counter <= 5) {
        // 小于等于 5 次提供建议

        let lunch = ranChoose(lunches)

        document.querySelector(".tip").outerHTML = `
        <h1 class="tip">今天午餐吃:<span class="lunch">${lunch}</span></h1>
        `
    } else {
        // 大于 5 次不伺候
        document.querySelector(".tip").outerHTML = `
        <h1 class="tip">太挑剔了不伺候</span></h1>
        `
        document.querySelector(".btn").disabled = true
    }
}

</script> $$

$$answer

$$jsdemo$$
$$edit$$
<div class="container">
    <h1 class="tip">让我来决定你午餐吃啥~</h1>
    <!-- <h1 class="tip">今天午餐吃:<span class="lunch">牛肉面</span></h1> -->
    <button class="btn" onclick="ranLunch()">随机大餐</button>
</div>

<style>
    .container {
        text-align: center;
    }

    .lunch {
        color: teal;
        font-size: 1.2em;
    }
</style>
<script>
    let lunches = [
        "牛肉面",
        "盖浇饭",
        "蛋炒饭",
        "烧饼",
        "黄焖鸡",
        "麻辣烫",
        "烤鸭",
    ]

    function ranChoose(array) {
        // 从数组中随机选择一个元素

        let idx = array.length * Math.random()

        idx = Math.floor(idx)

        return array[idx]
    }

    let counter = 0

    function ranLunch() {
        // 随机大餐

        counter++
        if (counter <= 5) {
            // 小于等于 5 次提供建议

            let lunch = ranChoose(lunches)

            document.querySelector(".tip").outerHTML = `
            <h1 class="tip">今天午餐吃:<span class="lunch">${lunch}</span></h1>
            `
        } else {
            // 大于 5 次不伺候
            document.querySelector(".tip").outerHTML = `
            <h1 class="tip">太挑剔了不伺候</span></h1>
            `
            document.querySelector(".btn").disabled = true
        }
    }
</script>

$$