首页 > web前端 > js教程 > JavaScript中舍入数字的指南

JavaScript中舍入数字的指南

Joseph Gordon-Levitt
发布: 2025-02-09 11:32:10
原创
575 人浏览过

A Guide to Rounding Numbers in JavaScript

本文探讨JavaScript中各种数字舍入方法,包括使用JavaScript数学函数和其他舍入到小数位的方法。我们还将介绍舍入数字时需要注意的问题。

关键要点

  • JavaScript提供了几种舍入数字的方法,包括Math.roundMath.floorMath.ceilMath.truncMath.round舍入到最接近的整数,Math.floor向下舍入,Math.ceil向上舍入,Math.trunc截断数字的小数部分。
  • 对于将数字舍入到特定的小数位数或有效数字,JavaScript提供Number.toFixedNumber.toPrecision方法。这些方法将舍入后的数字作为字符串返回。
  • 在处理负数时,Math.roundMath.floorMath.ceilMath.trunc的行为有所不同。例如,Math.floor将负数向下舍入到下一个最小的整数,而Math.trunc截断小数部分,有效地将其向上舍入。
  • 由于数字的二进制表示,JavaScript中可能会出现精度问题。某些十进制数无法在二进制中精确表示,从而导致舍入误差。Math.fround方法可用于查找32位中最接近的可表示数字。
  • 舍入方法的选择取决于具体的用例。Math.round是舍入到最接近整数的良好通用选择,但Math.floorMath.ceilMath.trunc可能更适合始终向下或向上舍入,或处理负数。Number.toFixedNumber.toPrecision应用于舍入到特定的小数位数或有效数字。

JavaScript舍入

在处理数值时,我们有时会执行计算,这些计算最终会产生需要舍入到整数的小数部分——例如,当您计算平均价格或处理随机数时。幸运的是,JavaScript的Math对象提供了许多将数字舍入到整数值的方法。

在我们的示例中,我们将使用两个最重要的数学常数来演示不同类型的舍入:π(圆的周长与其直径之比)和e(自然对数的底数,也称为“欧拉数”)。这两个值都是Math对象的属性,但让我们将它们赋值给一些变量,以便更容易处理:

const PI = Math.PI;
const E = Math.E;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

专业提示:您还可以使用对象解构在一行中进行此赋值:

const { PI, E } = Math;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

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

使用Math.round在JavaScript中舍入数字

我们将要查看的第一个方法是Math.round。这是最直接的选择,它只是将任何带有小数部分的数字舍入到最接近的整数。它使用以下规则:如果一个数字正好位于两个整数之间,则将其向上舍入。例如,2.5将向上舍入到3。

要使用此方法,我们只需提供要舍入的数字作为参数:

const PI = Math.PI;
const E = Math.E;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

如果您想将数字舍入到最接近的整数值,Math.round()非常方便。例如,如果您要计算三次测试的平均分数,则将三个分数相加并除以三。这可能不会得到一个整数,因此您可以使用Math.round()将其舍入到最接近的值:

const { PI, E } = Math;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

使用Math.floor舍入数字

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

Math.round(2.3); // 因为更接近2,所以向下舍入

Math.round(2.921); // 因为更接近3,所以向上舍入

Math.round(2.5); // 因为正好位于中间,所以向上舍入

Math.round(PI);

Math.round(E);
登录后复制
登录后复制
登录后复制
登录后复制

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

const test1 = 86;
const test2 = 93;
const test3 = 95;
const average = Math.round((test1 + test2 + test3) / 3);
登录后复制
登录后复制
登录后复制

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

使用Math.ceil舍入数字

说到向上舍入,这正是Math.ceil所做的。这个名称来自“天花板”,与“地板”相反,这意味着值正在上升。此方法的工作方式与所有其他方法相同。只需提供要向上舍入的数字作为参数:

Math.floor(2.3); // 向下舍入到2

Math.floor(2.921); // 向下舍入到2

Math.floor(2.5); // 向下舍入到2

Math.floor(PI);

Math.floor(E);
登录后复制
登录后复制
登录后复制

但是,您何时需要向上舍入一个数字呢?一个常见的用法是,如果您需要计算需要多少个容器来容纳某物。例如,假设您有一个包含播放列表的音乐网站,每个播放列表包含十首歌曲。如果有人上传了82首歌曲,您需要计算出要创建多少个播放列表。这是通过将歌曲数量除以10(每个播放列表中的歌曲数量)来完成的:

const fruit = ["?", "?", "?", "?", "?"];

const randomFruit = fruit[Math.floor(Math.random() * fruit.length)];
登录后复制
登录后复制

使用Math.round会将其向下舍入到8……但是,我们不会为最后两首歌曲创建一个播放列表!在这种情况下,我们始终需要向上舍入,以便为任何余数提供额外的容器:

Math.ceil(2.3); // 向上舍入到3

Math.ceil(2.921); // 向上舍入到3

Math.ceil(2.5); // 向上舍入到3

Math.ceil(PI);

Math.ceil(E);
登录后复制
登录后复制

使用Math.trunc舍入数字

我们将要查看的下一个方法是Math.trunc。严格来说,这不是一个舍入函数;它实际上是截断提供的参数数字。它基本上只是删除数字的小数部分,只留下整数部分,如下面的示例所示:

const PI = Math.PI;
const E = Math.E;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

乍一看,Math.trunc似乎与Math.floor相同;当然,到目前为止给出的所有示例都给出了相同的结果。但是,当提供负值作为参数时,这两种方法的行为有所不同,如下面的示例所示:

const { PI, E } = Math;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

差异发生是因为,当使用Math.floor向下舍入负数时,它会向下舍入到下一个最小的整数,而截断负值等效于将其向上舍入。

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

Math.round(2.3); // 因为更接近2,所以向下舍入

Math.round(2.921); // 因为更接近3,所以向上舍入

Math.round(2.5); // 因为正好位于中间,所以向上舍入

Math.round(PI);

Math.round(E);
登录后复制
登录后复制
登录后复制
登录后复制

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

在JavaScript中将数字舍入到小数位

我们已经看到Math.round会将数字舍入到最接近的整数。不幸的是,Math对象没有提供任何方法可以更精确地将数字舍入到特定的小数位数。幸运的是,Number类型有一些内置方法可以做到这一点。让我们来看看它们。

使用Number.toFixed舍入到小数位

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

const test1 = 86;
const test2 = 93;
const test3 = 95;
const average = Math.round((test1 + test2 + test3) / 3);
登录后复制
登录后复制
登录后复制

需要注意的一点是,该值作为字符串返回。您可以通过将方法调用包装在Number函数中来解决此问题,这会将结果转换回数字:

Math.floor(2.3); // 向下舍入到2

Math.floor(2.921); // 向下舍入到2

Math.floor(2.5); // 向下舍入到2

Math.floor(PI);

Math.floor(E);
登录后复制
登录后复制
登录后复制

还要注意:如果您尝试将此方法应用于已经是整数的数字,则如果只使用单个点调用该方法,则会出错:

const fruit = ["?", "?", "?", "?", "?"];

const randomFruit = fruit[Math.floor(Math.random() * fruit.length)];
登录后复制
登录后复制

您不能使用单个点在整数上调用方法,因为不清楚点是方法调用运算符还是小数点。要解决此问题,您可以将整数放在括号中或使用两个点,以便清楚地表明您正在调用方法而不是编写带有小数点的数字文字:

Math.ceil(2.3); // 向上舍入到3

Math.ceil(2.921); // 向上舍入到3

Math.ceil(2.5); // 向上舍入到3

Math.ceil(PI);

Math.ceil(E);
登录后复制
登录后复制

如果没有提供参数,则数字将舍入到最接近的整数(但作为字符串返回):

const songsPerPlaylist = 10;
const numberOfSongs = 82;
const numberOfPlaylists = numberOfSongs / songsPerPlaylist;
登录后复制

舍入到设定的几位小数的一个常见用例是处理货币——例如,如果您想以最接近美分的美元提供某物的价格。假设您有一个电子商务网站,正在进行促销活动,购物车中的任何商品都可享受15%的折扣。在显示折扣价格之前,可能需要对其进行舍入:

const numberOfPlaylists = Math.ceil(numberOfSongs / songsPerPlaylist);
登录后复制

这可以使用Number.toFixed轻松修复:

Math.trunc(2.3); // 只留下2

Math.trunc(2.921); // 只留下2,即使它更接近3

Math.trunc(2.5); // 只留下2

Math.trunc(PI);

Math.trunc(E);
登录后复制

注意:有关您可能遇到的toFixed()问题的更多信息,请参阅Number().toFixed()舍入错误:已损坏但可修复。

使用Number.toPrecision舍入到小数位

Number.toPrecision方法的工作方式类似于Number.toFixed方法,但它将数字舍入到固定数量的有效数字。

如果您需要快速提醒有效数字,它基本上意味着只使用第一个非零数字。对于大数,最终答案也将用零填充。例如,舍入到两位有效数字的数字53,863将变为54,000。这是因为5和3是前两位非零数字,并且由于下一个数字是8,所以它向上舍入。我们需要在末尾添加零以确保舍入值是原始数字的合理近似值。

您也可以以类似的方式舍入小数。例如,0.00000623978将舍入到0.0000062到两位有效数字,因为6和2是前两位非零数字,并且由于下一个数字是3,所以它向下舍入。

要使用此方法,只需在数字上调用它,并提供有效数字的数量作为参数(记住,整数需要在调用它们之前放在括号中):

const PI = Math.PI;
const E = Math.E;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

请注意,所有值都作为字符串返回,并且可以使用指数表示法——例如“5.4e 4”而不是“54000”。

如前所述,我们可以通过将方法调用包装在Number函数中来确保返回一个数字:

const { PI, E } = Math;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

舍入到给定有效数字的一个常见用途是当您处理大数并且不确定它们到底有多大时。例如,假设您想报告最新帖子被“点赞”的次数,您是将其舍入到最接近的10、100还是1000?在某种程度上,这取决于它的流行程度;如果它只获得8个赞,您不希望将其舍入到最接近的100,但如果它获得数千个赞,那么将其舍入到最接近的10似乎很愚蠢。解决方案是将其舍入到一位有效数字:

Math.round(2.3); // 因为更接近2,所以向下舍入

Math.round(2.921); // 因为更接近3,所以向上舍入

Math.round(2.5); // 因为正好位于中间,所以向上舍入

Math.round(PI);

Math.round(E);
登录后复制
登录后复制
登录后复制
登录后复制

JavaScript中舍入数字的问题

在JavaScript(或任何编程语言)中舍入数字时,需要注意一些事项。正如您可能知道的那样,计算机将所有数据(包括数字)存储为二进制表示。JavaScript将数字存储为32位单精度二进制值。

这样做的一个问题是,某些十进制数无法在二进制中精确表示。这通常不会造成任何问题,但它确实会导致一些奇怪的结果,例如:

const test1 = 86;
const test2 = 93;
const test3 = 95;
const average = Math.round((test1 + test2 + test3) / 3);
登录后复制
登录后复制
登录后复制

这是因为0.1和0.2无法在二进制中精确表示,并且在将它们相加时会产生轻微的误差。

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

Math.floor(2.3); // 向下舍入到2

Math.floor(2.921); // 向下舍入到2

Math.floor(2.5); // 向下舍入到2

Math.floor(PI);

Math.floor(E);
登录后复制
登录后复制
登录后复制

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

const PI = Math.PI;
const E = Math.E;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

如您所见,它非常接近0.1,但非常略高。在大多数实际情况下,这不会造成任何问题,但当您尝试舍入某些数字时,它偶尔会造成一些奇怪的行为:

const { PI, E } = Math;
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

发生这种情况是因为十进制3.55无法使用32位精确表示。我们可以使用Math.fround来查看它的实际表示方式:

Math.round(2.3); // 因为更接近2,所以向下舍入

Math.round(2.921); // 因为更接近3,所以向上舍入

Math.round(2.5); // 因为正好位于中间,所以向上舍入

Math.round(PI);

Math.round(E);
登录后复制
登录后复制
登录后复制
登录后复制

如您所见,它实际上由浮点数3.549999952316284表示,它向下舍入到3.5。

JavaScript中舍入数字的这些问题并不经常发生,但是如果您正在进行大量舍入,尤其是在结果必须准确的情况下,您绝对应该注意这些问题。

我应该使用哪些舍入数字的方法?

有了本文中介绍的所有舍入方法,您可能会问哪种方法最好用。答案总是“这取决于”。

如果您只想将数字舍入到最接近的整数,那么使用Math.round不会出错,但是如果您始终希望向下或向上舍入,而不管小数部分是什么,您也应该考虑使用Math.floorMath.ceil。如果您还计划舍入负数,请考虑改用Math.trunc

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

您可以在下面的CodePen演示中看到本文中介绍的所有不同类型的舍入示例。

CodePen演示链接

有了所有这些不同的方法,您以后应该不会再有舍入数字的问题了。

如果您觉得这篇文章有用,您可能还会喜欢这些:

  • JavaScript数字趣闻
  • 快速提示:如何在JavaScript中将数字转换为序数

关于在JavaScript中舍入数字的常见问题解答

如何在JavaScript中将数字舍入到最接近的整数?您可以使用Math.round()函数将数字舍入到最接近的整数。例如,Math.round(3.14)将得到3,Math.round(4.76)将得到5。

Math.round()Math.floor()Math.ceil()有什么区别?Math.round()舍入到最接近的整数,Math.floor()向下舍入到最接近的整数,Math.ceil()向上舍入到最接近的整数。

我可以将数字舍入到特定的小数位数吗?是的,您可以使用toFixed()方法将数字舍入到特定的小数位。例如,let roundedNumber = 3.14159.toFixed(2)将得到3.14。

Math.round()如何处理具有.5小数部分的数字?Math.round()使用“四舍五入”逻辑,这意味着当小数部分正好为.5时,它会舍入到最接近的偶数整数。例如,Math.round(2.5)的结果为2,Math.round(3.5)的结果为4。

我可以使用Math.round()舍入正数和负数吗?是的,Math.round()适用于正数和负数。它像往常一样舍入正数,并将负数舍入到零。

JavaScript中会发生舍入错误吗?是的,由于计算机中浮点运算的工作方式,可能会发生舍入错误。务必注意潜在的精度问题,尤其是在处理非常大或非常小的数字时。在这种情况下,请考虑使用像decimal.js这样的库来进行更精确的算术运算。

以上是JavaScript中舍入数字的指南的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板