JavaScript中的四舍五入指南

2,642 阅读11分钟

JavaScript中的四舍五入指南

在这篇文章中,我们将探讨在JavaScript中对数字进行四舍五入的各种方法。这包括使用JavaScript数学函数,以及其他四舍五入的方法。我们还将介绍四舍五入时需要注意的问题。

JavaScript四舍五入

在处理数值的时候,我们有时会在计算中出现需要四舍五入的小数部分--比如在计算平均价格的时候,或者在处理随机数字的时候。值得庆幸的是,JavaScript的Math 对象提供了一些将数字四舍五入为整数的方法。

在我们的例子中,我们将使用两个最重要的数学常数来演示不同类型的四舍五入。Pi是圆的周长与直径的比值,e是自然对数的基数,也被称为 "欧拉数"。这两个值都是Math 对象的属性,但让我们把它们分配给一些变量,使它们更容易处理。

const PI = Math.PI
const E = Math.E

专业提示:你也可以使用对象去结构化在一行中进行这种分配。

const { PI,E } = Math

现在我们已经定义了这些常量,让我们来看看JavaScript中四舍五入的一些方法。

在JavaScript中用Math.round对数字进行四舍五入

我们要看的第一个方法是Math.round 。这是最直接的选择,它简单地将任何带有小数部分的数字舍入到最接近的整数。它使用这个规则:如果一个数字正好在两个整数的中间,它将被四舍五入。例如,2.5将被四舍五入为3。

要使用这个方法,我们只需提供我们想四舍五入的数字作为参数:

Math.round(2.3) // rounds down because it's closer to 2
<< 2

Math.round(2.921) // rounds up because it's closer to 3
<< 3

Math.round(2.5) // rounds up because it's exactly halfway
<< 3

Math.round(PI)
<< 3

Math.round(E)
<< 3

Math.round() 如果你想把一个数字四舍五入到最接近的整数值,就会很方便。例如,如果你要计算三次测试的平均分数,你就把三次的分数加起来,然后除以3。这可能不是一个整数,所以你会用 ,把它四舍五入到最接近的值。Math.round()

const test1 = 86;
const test2 = 93;
const test3 = 95;
const average = Math.round((test1+test2+test3)/3);
<< 91

用Math.floor对数字进行四舍五入

我们要看的下一个方法是Math.floor 。这个方法总是将一个值向下舍入到下面的整数(名字意味着这个数字被推到了地板上):

Math.floor(2.3) // rounds down to 2
<< 2

Math.floor(2.921) // rounds down to 2
<< 2

Math.floor(2.5) // rounds down to 2
<< 2

Math.floor(PI)
<< 3

Math.floor(E)
<< 2

Math.floor 的一个常见用途是在创建随机整数时。四舍五入可以确保整数从零开始,并且每个整数都有相同的机会被返回。从零开始通常是有用的,因为JavaScript中的数组是以零为索引的,所以向下舍入可以确保数组中的第一个元素可以被选中。下面的例子显示了如何使用Math.floor 从一个数组中选择一个随机元素。

const fruit = ["🍏","🍌","🍓","🍋","🍐"]

const randomFruit = fruit[Math.floor(Math.random()*fruit.length)]
<< "🍓"

在上面的代码中,使用Math.floor 向下舍入可以确保返回0到4之间的索引,所以数组中的每个元素都有相同的机会被选中。

使用Math.ceil对数字进行四舍五入

说到四舍五入,这正是Math.ceil 的作用。这个名字来自于天花板,与地板相反,意味着数值在上升。该方法的工作方式与其他方法相同。只要提供你想四舍五入的数字作为参数。

Math.ceil(2.3) // rounds up to 3
<< 3

Math.ceil(2.921) // rounds up to 3
<< 3

Math.ceil(2.5) // rounds up to 3
<< 3

Math.ceil(PI)
<< 4

Math.ceil(E)
<< 3

但是,你什么时候需要对一个数字进行四舍五入呢?一个常见的用法是,如果你需要计算出你需要多少个容器来装什么东西。例如,假设你有一个包括播放列表的音乐网站,每个播放列表上有十首歌曲。如果有人上传了82首歌曲,你需要计算出要创建多少个播放列表。这是通过将歌曲数量除以10 (每个播放列表上的歌曲数量)来完成的。

const songsPerPlaylist = 10;
const numberOfSongs = 82;
const numberOfPlaylists = numberOfSongs/songsPerPlaylist;
<< 8.2

使用Math.round 可以其四舍五入为8......但这样我们就没有最后两首歌曲的播放列表了。在这种情况下,我们总是需要四舍五入,以便有一个额外的容器来容纳任何余数。

const numberOfPlaylists = Math.ceil(numberOfSongs/songsPerPlaylist);
<< 9

用Math.trunc对数字进行四舍五入

我们要看的下一个方法是Math.trunc 。严格地说,这不是一个四舍五入函数;它实际上是截断了作为参数的数字。它基本上只是去掉了数字的小数部分,只留下了整数部分,在下面的例子中可以看到这一点。

Math.trunc(2.3) // just leaves 2
<< 2

Math.trunc(2.921) // just leaves 2, even though it's closer to 3
<< 2

Math.trunc(2.5) // just leaves 2
<< 2

Math.trunc(PI)
<< 3

Math.trunc(E)
<< 2

乍一看,Math.trunc 似乎与Math.floor 相同;当然,到目前为止给出的例子都给出了同样的结果。然而,当提供一个负值作为参数时,这两个方法的表现是不同的,在下面的例子中可以看到。

Math.floor(-2.3) // rounds DOWN to -3
<< -3

Math.trunc(-2.3) // removes the decimal part, leaving just -2
<< -2

出现这种差异的原因是,当使用Math.floor 将一个负数四舍五入时,它将下降到下一个最低的整数,而截断一个负值相当于将其向上舍入。

Math.ceil 当参数为负数时, ,返回与之相同的值。Math.trunc

Math.trunc(-2.3) // removes the decimal part, leaving just -2
<< -2

Math.ceil(-2.3) // rounds UP to -2
<< -2

所有这些方法都非常有用,但它们都有一个局限性,即它们总是返回整数值。如果我们想把一个数字四舍五入到一定的小数位或有效数字,怎么办?

在JavaScript中把数字四舍五入到小数位上

我们已经看到,Math.round 将把数字四舍五入到最接近的整数。不幸的是,Math 对象并没有提供任何方法来更准确地将数字四舍五入到小数点后的某一数字。值得庆幸的是,Number 类型有几个内置方法可以做到这一点。让我们来看看它们。

用Number.toFixed四舍五入到小数位数

这是一个数字方法,这意味着它是由数字本身调用的。它将一个小数四舍五入到给定的小数位数,这个小数位数是作为一个参数提供的。

2.4387587.toFixed(2) // rounds to 2 decimal places
<< "2.44"

需要注意的是,该值是以字符串形式返回的。你可以通过将方法调用包裹在Number 函数中来解决这个问题,它将把结果转换为数字

Number(2.4387587.toFixed(2))
<< 2.44

还需要注意的是:如果你试图对一个已经是整数的数字应用这个方法,如果你只是用一个点来调用这个方法,你会得到一个错误。

2.toFixed(2)
<< SyntaxError

你不能用一个点来调用整数的方法,因为不清楚这个点是一个方法调用操作符还是一个小数点。为了解决这个问题,你可以把整数放在括号里,或者使用两个点,这样就可以清楚地知道你在调用一个方法,而不是写出一个带有小数点的数字字面。

(2).toFixed(2)
<< "2.00"

2..toFixed(2)
<< "2.00"

如果没有提供参数,数字将被四舍五入为最接近的整数(但作为一个字符串返回)。

PI.toFixed()
<< "3"

E.toFixed()
<< "3"

四舍五入到设定的小数位数的一个常见用例是在处理货币时--例如,如果你想提供某个东西的美元价格到最近的美分。比方说,你有一个电子商务网站,正在进行促销活动,购物车里的任何东西都打八五折。折扣后的价格可能需要在显示之前进行四舍五入。

const item1Price = 2.99
const item2Price = 4.99
const item3Price = 6.20

const totalPrice = item1Price + item2Price + item3Price
const discountedPrice = 0.85 * totalPrice
<< 12.052999999999999

这可以很容易地用Number.toFixed

const discountedPrice = (0.85 * totalPrice).toFixed(2)
<< "12.05"

注意:关于你可能面临的toFixed() ,请参阅Number().toFixed() Rounding Errors。破损但可修复

用Number.toPrecision将数字四舍五入到小数点位上

Number.toPrecision 方法的工作方式与Number.toFixed 方法类似,但它将数字四舍五入到一个固定的有效数字

如果你需要快速提醒一下有效数字,它基本上意味着只使用第一个非零位数。对于大数字,最终的答案也会用零来填充。例如,数字53,863四舍五入到两个有效数字后将变成54,000。这是因为5和3是前两个非零数字,四舍五入是因为下一个数字是8,我们需要在最后加零,以确保四舍五入后的数值合理地接近于原始数字。

你也可以用类似的方式对小数进行四舍五入。例如,0.00000623978将四舍五入为0.0000062到两个有效数字,因为6和2是第一个非零数字,它向下舍入是因为下一个数字是3。

要使用这个方法,只需在数字上调用它,提供有效数字作为参数(记住,整数在调用方法之前需要放在括号里)。

(53863).toPrecision(2)
<< "5.4e+4"

0.00000623978.toPrecision(2)
<< 0.0000062"

注意,所有的值都以字符串形式返回,可以使用指数符号--比如 "5.4e+4 "而不是 "54000"。

和以前一样,我们可以通过将方法调用包裹在Number 函数中来确保返回一个数字。

Number((53863).toPrecision(2))
<< 54000

四舍五入的一个常见用途是,当你处理大数字时,你不确定它们会有多大。例如,如果你想报告你最新的帖子被 "赞 "了多少次,你是把它四舍五入到最接近的10、100还是1000?在某种程度上,这取决于它有多受欢迎;如果它只得到8个赞,你不想把它四舍五入到最接近的100,但如果它得到成千上万个赞,那么把它四舍五入到最接近的10似乎很愚蠢。解决的办法是四舍五入到一个有效数字。

const unpopularPost = 8;
const quitePopularPost = 387;
const poplularPost = 79671;

Number(unpopularPost.toPrecision(1))
<< 8
Number(quitePopularPost.toPrecision(1))
<< 400
Number(poplularPost.toPrecision(1))
<< Number(poplularPost.toPrecision(1))
<< 80000

在JavaScript中对数字进行四舍五入的问题

在JavaScript(或任何编程语言)中对数字进行四舍五入时,有几件事需要注意。你可能知道,计算机存储所有的数据--包括数字--都是二进制表示。JavaScript将数字存储为32位单精度二进制值。

这样做的问题是,一些以10为基数的数字不能准确地以2为基数表示。这通常不会造成任何问题,但它确实会造成一些奇怪的结果,比如说这个。

0.1 + 0.2 === 0.3
<< false

这是因为0.1和0.2不能准确地用二进制表示,在将它们相加时,会出现一个小错误。

Math 对象有另一个方法,叫做fround ,它返回可以用32位表示的最接近的数字。例如,0.6125可以用二进制精确表示为0.101,所以这将返回相同的值。

Math.fround(0.625)
<< 0.625

但是,正如我们在上面看到的,0.1不能用32位精确表示。Math.fround ,向我们显示可以表示的最接近的数字。

Math.fround(0.1)
<< 0.10000000149011612

正如你所看到的,它非常接近于0.1,但略高。在大多数实际情况下,这不会造成任何问题,但当你试图对一些数字进行四舍五入时,它偶尔会造成一些奇怪的行为。

3.55.toFixed(1) // should round UP to 3.6
<< "3.5"

发生这种情况是因为小数3.55不能用32位来准确表示。我们可以使用Math.fround ,看看它究竟是如何表示的。

Math.fround(3.55)
<< 3.549999952316284

正如你所看到的,它实际上是由浮点数3.5499952316284表示的,它向下舍入为3.5。

这些在JavaScript中四舍五入的问题并不经常发生,但如果你要做大量的四舍五入,你肯定要注意这些问题--尤其是当结果很重要的时候。

我应该使用哪些方法来进行四舍五入?

在这个四舍五入总结中提出了所有的四舍五入方法,你可能会问哪个是最好用的。一如既往,答案是:"这取决于"。

如果你只是想把一个数字四舍五入到最接近的整数,你不能用Math.round ,但如果你总是想向下或向上四舍五入,不管小数部分是什么,你也应该考虑使用Math.floorMath.ceil 。如果你还打算对负数进行四舍五入,可以考虑使用Math.trunc 来代替。

如果你需要四舍五入到指定的小数位数或有效数字,你必须使用Number.toFixedNumber.toPrecision 。但要注意,这两个方法是由数字调用的,并返回一个字符串

你可以在下面的CodePen演示中看到本文中涉及的所有不同类型的四舍五入的例子。