ChatGPT解决这个技术问题 Extra ChatGPT

如有必要,如何舍入至多 2 位小数

我想最多四舍五入小数点后两位,但仅限于必要时。

输入:

10
1.7777777
9.1

输出:

10
1.78
9.1

如何在 JavaScript 中做到这一点?

你不能。请参阅我在 this question 中的答案,了解为什么不这样做,并附上证据。
@user207421 您的链接指向这个问题,但如果“这个问题”是指这个问题,那么您对这个问题没有答案。 PS谷歌搜索......我想你可能是指stackoverflow.com/questions/153724/…

u
user229044

使用 Math.round()

Math.round(num * 100) / 100

或者更具体地说,为了确保 1.005 正确舍入,请使用 Number.EPSILON

Math.round((num + Number.EPSILON) * 100) / 100

@PSatishPatro(我假设您的意思是说 224.99 而不是 224.95)。如果您要四舍五入到小数点后第二位(百分之一),那么我们应该只关心小数点后第三位(千位)是什么数字以及之后的所有内容。所以从输入 224.98499999 来看,只有 224.984 重要,这意味着 224.98 是正确的。
Math.round(1.255 * 100) / 100 将是 1.25 。这是错的
@PSatishPatro,我意识到,我们离题了,但是将 224.9849... 四舍五入到小数点后两位,无论用任何语言还是手动,都应该得到 224.98。如果你得到 224.99,恐怕你做错了。考虑它的最简单方法是,您正在寻找只有两位小数的最接近的数字。虽然没有太大区别,但 224.9849 更接近 224.98 而不是 224.99。
我发现 10.075 舍入错误。给出 10.07 而不是 10.08,即使使用 epsilon 修复。
Math.round((519.805+ Number.EPSILON) * 100) / 100,四舍五入为 519.8
P
Peter Mortensen

如果值是文本类型:

parseFloat("123.456").toFixed(2);

如果值是一个数字:

var numb = 123.23454;
numb = numb.toFixed(2);

有一个缺点是,像 1.5 这样的值会给出“1.50”作为输出。 @minitech 建议的修复:

var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.

似乎 Math.round 是一个更好的解决方案。 但事实并非如此!在某些情况下,它会正确四舍五入:

Math.round(1.005 * 100)/100 // Returns 1 instead of expected 1.01!

在某些情况下,toFixed() 也不会正确舍入(在 Chrome v.55.0.2883.87 中测试)!

例子:

parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.

1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.

我猜,这是因为 1.555 实际上在幕后类似于 float 1.55499994。

解决方案 1 是使用具有所需舍入算法的脚本,例如:

function roundNumber(num, scale) {
  if(!("" + num).includes("e")) {
    return +(Math.round(num + "e+" + scale)  + "e-" + scale);
  } else {
    var arr = ("" + num).split("e");
    var sig = ""
    if(+arr[1] + scale > 0) {
      sig = "+";
    }
    return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
  }
}

它也是at Plunker

注意:这不是一个适合所有人的通用解决方案。有几种不同的舍入算法。您的实现可能会有所不同,这取决于您的要求。另请参阅Rounding

解决方案 2 是避免前端计算并从后端服务器拉取舍入值。

另一种可能的解决方案,也不是万无一失的。

Math.round((num + Number.EPSILON) * 100) / 100

在某些情况下,当您对 1.3549999999999998 之类的数字进行四舍五入时,它会返回错误的结果。它应该是 1.35,但结果是 1.36。


在这个函数 roundNumberV2 中有这个条件 if (Math.pow(0.1, scale) > num) { return 0; }。我可以知道这个条件的目的是什么吗?
性能也应该是一个问题,这可能会使这种方法不太理想。 Math.round() 快得多jsbin.com/kikocecemu/edit?js,output
请注意,作为对某人的提醒,因为这让我很生气,但是如果您想做类似 var a = parseFloat(1/3).toFixed(2); 的事情,当您执行 var c = a + someNumber; 时它似乎不喜欢它 - 它会像您尝试添加一样对待它一个字符串(那里的新 a)到一个数字(someNumber)。所以可能需要做var c = eval(a) + someNumber;
注意:“从字符串执行 JavaScript 存在巨大的安全风险。当您使用 eval() 时,坏人很容易运行任意代码”,请参阅 MDN 文档 here
您应该使用 Number(a)parseFloat(a)(实际上与 stackoverflow.com/a/11988612/16940 的行为相同)而不是 eval(a)。您甚至可以只使用 +a。我更喜欢Number(a)
P
Peter Mortensen

您可以使用

function roundToTwo(num) {
    return +(Math.round(num + "e+2")  + "e-2");
}

我找到了这个 on MDN。他们的方式避免了 1.005 was mentioned 的问题。

roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57

@Redsandro,+(val) 是使用 Number(val) 的强制等效项。将“e-2”连接到数字会导致需要将字符串转换回数字。
用 e 传递一个数字,它返回 NaN,例如 1.19e-7
这不适用于负数。
但是,如果 num 为 -2.9e-7,则 +(Math.round(num + "e+2") + "e-2") 返回 NaN,这不是所需的结果。至少在 Chrome 101 上
P
Peter Mortensen

MarkG's answer 是正确的。这是任意小数位数的通用扩展。

Number.prototype.round = function(places) {
  return +(Math.round(this + "e+" + places)  + "e-" + places);
}

用法:

var n = 1.7777;    
n.round(2); // 1.78

单元测试:

it.only('should round floats to 2 places', function() {
    
  var cases = [
    { n: 10,      e: 10,    p:2 },
    { n: 1.7777,  e: 1.78,  p:2 },
    { n: 1.005,   e: 1.01,  p:2 },
    { n: 1.005,   e: 1,     p:0 },
    { n: 1.77777, e: 1.8,   p:1 }
  ]
    
  cases.forEach(function(testCase) {
    var r = testCase.n.round(testCase.p);
    assert.equal(r, testCase.e, 'didn\'t get right number');
  });
})

我发现这个独立(无 prototype 扩展)版本 (ES6) 易于阅读且直截了当:round = (num, precision) => Number(Math.round(num + "e+" + precision) + "e-" + precision);
如果输入数字已经是指数形式怎么办?你会得到 NaN
我在此 (Math.round(number + "e+" + places)) 中收到此错误“字符串”类型的参数不可分配给 Typescript 中“数字”类型的参数
为了适应非常小和非常大的数字,它们将自动呈指数形式,您可以使用 toFixed 解决这个问题。即function round(val, decimals) { return +(Math.round(+(val.toFixed(decimals) + "e+" + decimals)) + "e-" + decimals); }
哦,来吧,不要修改原型
c
cronvel

你应该使用:

Math.round( num * 100 + Number.EPSILON ) / 100

似乎没有人知道 Number.EPSILON

另外值得注意的是,这并不是某些人所说的 JavaScript 怪异。

这就是浮点数在计算机中的工作方式。 与 99% 的编程语言一样,JavaScript 没有自制浮点数。它依赖于 CPU/FPU。计算机使用二进制,而在二进制中,没有像 0.1 这样的数字,而只是一个二进制近似值。为什么?出于同样的原因,1/3 不能写成十进制:它的值是 0.33333333... 有无穷多个三。

来了Number.EPSILON。该数字是 1 与双精度浮点数中存在的 next 数字之间的差。 就是这样:1 和 1 + Number.EPSILON 之间没有数字。

编辑:

正如评论中所要求的,让我们澄清一件事:添加 Number.EPSILON 仅当要舍入的值是算术运算的结果时才相关,因为它可以吞下一些浮点错误增量。

当值来自直接来源(例如:文字、用户输入或传感器)时,它没有用。

编辑(2019):

就像@maganap 和一些人指出的那样,最好在乘法之前添加 Number.EPSILON

Math.round( ( num + Number.EPSILON ) * 100 ) / 100

编辑(2019 年 12 月):

最近,我使用与此类似的函数来比较数字 epsilon 感知:

const ESPILON_RATE = 1 + Number.EPSILON ;
const ESPILON_ZERO = Number.MIN_VALUE ;

function epsilonEquals( a , b ) {
  if ( Number.isNaN( a ) || Number.isNaN( b ) ) {
    return false ;
  }
  if ( a === 0 || b === 0 ) {
    return a <= b + EPSILON_ZERO && b <= a + EPSILON_ZERO ;
  }
  return a <= b * EPSILON_RATE && b <= a * EPSILON_RATE ;
}

我的用例是an assertion + data validation lib我已经开发了很多年。

事实上,在代码中我使用了 ESPILON_RATE = 1 + 4 * Number.EPSILONEPSILON_ZERO = 4 * Number.MIN_VALUE(四倍 epsilon),因为我想要一个足够松散的相等检查器来累积浮点错误。

到目前为止,它看起来对我来说很完美。我希望它会有所帮助。


如果我想四舍五入到 3 个十进制数字,我应该使用 1000 而不是 100?
Math.round((224.98499999 * 100 + Number.EPSILON)) / 100 224.98 而不是 224.99
@PSatishPatro 没错。 .849 比 0.9 更接近 0.8,因此,它向下舍入为 0.8。
@RandomElephant,好的,但通常当我们计算时,我们会进行四舍五入,即从最后一位数字四舍五入。 98499 -> .9849 -> .985 -> .99 。有没有办法在js中实现这一点?
@PSatishPatro 有,但数学不正确。从最后一个数字开始没有一般的四舍五入,如果你这样做了,你真的需要考虑重新学习数学。编辑:要回答,您将获取数字的长度,并将它们从最后一个循环,四舍五入并更改初始数字,直到达到所需的位数。
A
Amr Ali

通常,小数舍入是通过缩放完成的:round(num * p) / p

幼稚的实现

使用以下带有中间数字的函数,您将获得预期的上舍入值,或者有时取决于输入的下舍入值。

inconsistency 舍入可能会在客户端代码中引入难以检测的错误。

函数 naiveRound(num, decimalPlaces = 0) { var p = Math.pow(10, decimalPlaces);返回 Math.round(num * p) / p; } console.log( naiveRound(1.245, 2) ); // 1.25 正确(按预期四舍五入) console.log( naiveRound(1.255, 2) ); // 1.25 不正确(应该是 1.26) // 测试边缘情况 console.log( naiveRound(1.005, 2) ); // 1 不正确(应该是 1.01) console.log( naiveRound(2.175, 2) ); // 2.17 不正确(应该是 2.18) console.log( naiveRound(5.015, 2) ); // 5.01 不正确(应该是 5.02)

为了判断舍入操作是否涉及中点值,Round 函数将要舍入的原始值乘以 10 ** n,其中 n 是返回值中所需的小数位数,然后判断剩余的小数是否值的一部分大于或等于 0.5。由于浮点格式在二进制表示和精度方面存在问题,因此具有浮点值的 "Exact Testing for Equality" 存在问题。这意味着任何略小于 0.5 的小数部分(由于精度损失)都不会向上舍入。

在前面的例子中,5.015是一个中点值,如果要四舍五入到小数点后两位,5.015 * 100的值实际上是501.49999999999994。因为 .49999999999994 小于 0.5,所以向下舍入为 501,最终结果为 5.01。

更好的实现

指数符号

通过将数字转换为指数符号中的字符串,正数按预期四舍五入。但是,请注意负数与正数的舍入方式不同。

事实上,它执行的规则基本上等同于 "round half up",您将看到 round(-1.005, 2) 的计算结果为 -1,即使 round(1.005, 2) 的计算结果为 1.01lodash _.round 方法使用了这种技术。

/** * 向上舍入一半('向正无穷方向舍入一半') * 负数舍入不同于正数。 */ function round(num, decimalPlaces = 0) { num = Math.round(num + "e" + decimalPlaces);返回数字(num +“e”+ -decimalPlaces); } // 测试一半的四舍五入 console.log( round(0.5) ); // 1 个控制台.log( round(-0.5) ); // 0 // 测试边缘案例 console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1 console.log( round(-2.175, 2) ); // -2.17 console.log( round(-5.015, 2) ); // -5.01

如果您希望在舍入负数时采用通常的行为,则需要在调用 Math.round() 之前将负数转换为正数,然后在返回之前将它们转换回负数。

// Round half away from zero
function round(num, decimalPlaces = 0) {
    if (num < 0)
        return -round(-num, decimalPlaces);

    num = Math.round(num + "e" + decimalPlaces);
    return Number(num + "e" + -decimalPlaces);
}

近似舍入

为了纠正前面 naiveRound 示例中显示的舍入问题,我们可以定义一个自定义舍入函数,该函数执行“几乎相等”测试以确定小数值是否足够接近中点值以进行中点舍入。

// 从零开始舍入一半 function round(num, decimalPlaces = 0) { if (num < 0) return -round(-num, decimalPlaces); var p = Math.pow(10, decimalPlaces);变量 n = 数量 * p; var f = n - Math.floor(n); var e = Number.EPSILON * n; // 判断这个分数是否为中点值。返回 (f >= .5 - e) ? Math.ceil(n) / p : Math.floor(n) / p; } // 测试一半的四舍五入 console.log( round(0.5) ); // 1 个控制台.log( round(-0.5) ); // -1 // 测试边缘情况 console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log(round(-5.015, 2) ); // -5.02

编号.EPSILON

有一种不同的纯数学技术来执行舍入到最近(使用 "round half away from zero"),其中在调用舍入函数之前应用 epsilon 校正。

简单地说,我们在舍入之前将最小可能的浮点值(= 1.0 ulp;最后一个单位)添加到产品中。这将移动到下一个可表示的浮点值,远离零,因此它将抵消在乘以 10 ** n 期间可能出现的二进制 round-off error

/** * 从零舍入一半(“商业”舍入) * 使用校正来抵消浮点不准确性。 * 对正数和负数对称地工作。 */ function round(num, decimalPlaces = 0) { var p = Math.pow(10, decimalPlaces); var n = (num * p) * (1 + Number.EPSILON);返回 Math.round(n) / p; } // 取整一半 console.log(round(0.5) ); // 1 个控制台.log( round(-0.5) ); // -1 // 测试边缘情况 console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log(round(-5.015, 2) ); // -5.02

添加 1 ulp 后,5.015 * 100 的值即 501.49999999999994 将被修正为 501.50000000000006,这将四舍五入为 502,最终结果为 5.02。

请注意,unit in last place(“ulp”)的大小由 (1) 数字的大小和 (2) 相对机器 epsilon (2^-52) 确定。 Ulp 在具有较大量级的数字上比在具有较小量级的数字上相对较大。

双舍入

在这里,我们使用 toPrecision() 方法去除中间计算中的浮点舍入误差。简单地说,我们舍入到 15 significant figures 以去除第 16 位有效数字的舍入误差。 PHP 7 round 函数也使用了这种将结果预舍入为有效数字的技术。

5.015 * 100 的值即 501.49999999999994 将首先四舍五入到 15 位有效数字为 501.500000000000,然后再次四舍五入到 502,最后结果为 5.02。

// 从零开始舍入一半 function round(num, decimalPlaces = 0) { if (num < 0) return -round(-num, decimalPlaces); var p = Math.pow(10, decimalPlaces); var n = (num * p).toPrecision(15);返回 Math.round(n) / p; } // 取整一半 console.log(round(0.5) ); // 1 个控制台.log( round(-0.5) ); // -1 // 测试边缘情况 console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log(round(-5.015, 2) ); // -5.02

任意精度的 JavaScript 库 - decimal.js

// 从零开始舍入一半 function round(num, decimalPlaces = 0) { return new Decimal(num).toDecimalPlaces(decimalPlaces).toNumber(); } // 取整一半 console.log(round(0.5) ); // 1 个控制台.log( round(-0.5) ); // -1 // 测试边缘情况 console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log(round(-5.015, 2) ); // -5.02


(1.005).toPrecision(3) 实际上仍然返回 1.00 而不是 1.01
toPrecision 返回一个更改所需输出类型的字符串。
@Giacomo 这不是 .toPrecision 方法的缺陷,它是浮点数的特殊性(JS 中的数字是)-尝试 1.005 - 0.005,它将返回 0.9999999999999999
(1).toPrecision(3) 返回“1.00”,但在这种情况下发问者希望有 1
正如@Giacomo 所说,这个答案似乎将“有效数字”与“四舍五入到小数位”混淆了。 toPrecision 执行格式,而不是后者,并且不是对 OP 问题的回答,尽管乍一看它可能看起来很相关,但它有很多错误。请参阅en.wikipedia.org/wiki/Significant_figures。例如,Number(123.4).toPrecision(2) 返回 "1.2e+2"Number(12.345).toPrecision(2) 返回 "12"。我也同意@adamduren 的观点,即它返回一个不可取的字符串(不是一个大问题,但不可取)。
M
Marcin Wanago

最简单的方法是使用 toFixed,然后使用 Number 函数去除尾随零:

const number = 15.5;
Number(number.toFixed(2)); // 15.5
const number = 1.7777777;
Number(number.toFixed(2)); // 1.78

这不适用于所有情况。在发布答案之前进行广泛的测试。
@baburao 请发布上述解决方案不起作用的案例
常量数 = 15;数字(数字.toFixed(2)); //15.00 而不是 15
@KevinJhangiani 常量数 = 15;数字(数字.toFixed(2)); // 15 - 我在最新的 Chrome 和 Firefox 上都测试过
评论者完全正确,发布后我意识到代码中的错误!
P
Peter Mortensen

MarkG and Lavamantis offered 比已被接受的解决方案要好得多。可惜他们没有得到更多的支持!

这是我用来解决浮点小数问题的函数 also based on MDN。它比 Lavamantis 的解决方案更通用(但不太简洁):

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp  = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

使用它:

round(10.8034, 2);      // Returns 10.8
round(1.275, 2);        // Returns 1.28
round(1.27499, 2);      // Returns 1.27
round(1.2345678e+2, 2); // Returns 123.46

与 Lavamantis 的解决方案相比,我们可以做...

round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123

与 MDN 的解决方案相反,您的解决方案不涵盖某些情况。虽然它可能更短,但它并不准确......
圆形(-1835.665,2)=> -1835.66
j
justinsg

仅在必要时实现这种舍入的一种方法是使用 Number.prototype.toLocaleString()

myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})

这将提供您期望的输出,但作为字符串。如果这不是您期望的数据类型,您仍然可以将它们转换回数字。


这是迄今为止最简洁的解决方案,并且回避了所有复杂的浮点问题,但 per MDN 支持仍然不完整 - Safari 尚不支持将参数传递给 toLocaleString
@MarkAmery 目前,只有 Android 浏览器有一些问题:caniuse.com/#search=toLocaleString
P
Peter Mortensen

它可能对你有用,

Math.round(num * 100)/100;

要知道 toFixed 和 round 之间的区别。你可以看看Math.round(num) vs num.toFixed(0) and browser inconsistencies


Math.round(1.965 * 100) / 100 将是 1.96 。这是错的。
S
Soldeplata Saketos

这是最简单、更优雅的解决方案(我是世界上最好的;):

function roundToX(num, X) {    
    return +(Math.round(num + "e+"+X)  + "e-"+X);
}
//roundToX(66.66666666,2) => 66.67
//roundToX(10,2) => 10
//roundToX(10.904,2) => 10.9

具有后备值的现代语法替代方案

const roundToX = (num = 0, X = 20) => +(Math.round(num + `e${X}`)  + `e-${X}`)

这是使用 E 表示法重写接受的答案以接受参数的好方法。
这在某些极端情况下不起作用:尝试 (jsfiddle) roundToX(362.42499999999995, 2)。预期结果(如 PHP echo round(362.42499999999995, 2)):362.43。实际结果:362.42
恕我直言,您的 PHP 结果是错误的。无论小数点后三位是什么,如果小数点后三位小于 5,那么小数点后二位应该保持不变。这就是数学定义。
为了更简洁,“e+”可以改为“e”。
P
Peter Mortensen
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2):这里 2 是我们希望将此数字四舍五入的位数。


这个 .toFixed() 实现起来更简单。只需经历一次。
一个解释将是有序的。例如,这个“数字”函数有什么作用?为什么需要它?想法/要点是什么?一些更多的输入和输出值也会很好,例如前面提到的1.005。来自 the Help Center“...总是解释为什么你提出的解决方案是合适的以及它是如何工作的”。请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的)。
P
Peter Mortensen

另一个简单的解决方案(不编写任何函数)可以使用 toFixed() 然后再次转换为浮点数:

例如:

var objNumber = 1201203.1256546456;
objNumber = parseFloat(objNumber.toFixed(2))

不,它仅对 (0).5 以上的值进行四舍五入。
K
KFish

请参阅@AmrAli 的答案,以更全面地了解此解决方案的所有各种调整和性能细分。

var DecimalPrecision = (function(){ if (Number.EPSILON === undefined) { Number.EPSILON = Math.pow(2, -52); } if(Number.isInteger === undefined){ Number.isInteger = function (value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; }; } this.isRound = function(n,p){ let l = n.toString ().split('.')[1].length; return (p >= l); } this.round = function(n, p=2){ if(Number.isInteger(n) || this.isRound (n,p)) 返回 n; 让 r = 0.5 * Number.EPSILON * n; 让 o = 1; 而(p-- > 0) o *= 10; if(n<0) o *= -1;返回 Math.round((n + r) * o) / o; } this.ceil = function(n, p=2){ if(Number.isInteger(n) || this.isRound(n,p)) 返回n; let r = 0.5 * Number.EPSILON * n; let o = 1; while(p-- > 0) o *= 10; return Math.ceil((n + r) * o) / o; } this. floor = function(n, p=2){ if(Number.isInteger(n) || this.isRound(n,p)) return n; 让 r = 0.5 * Number.EPSILON * n; 让 o = 1; 而(p-- > 0) o *= 10; return Math.floor((n + r) * o) / o; } return this; })(); console.log(DecimalPrecision.round(1.005)); console.log(DecimalPrecision.ceil(1.005)); console.log(DecimalPrecision.floor(1.005)); console.log(DecimalPrecision.round(1.0049999)); console.log(DecimalPrecision.ceil(1.0049999)); console.log(DecimalPrecision.floor(1.0049999)); console.log(DecimalPrecision.round(2.175495134384,7)); console.log(DecimalPrecision.round(2.1753543549,8)); console.log(DecimalPrecision.round(2.1755465135353,4)); console.log(DecimalPrecision.ceil(17,4)); console.log(DecimalPrecision.ceil(17.1,4)); console.log(DecimalPrecision.ceil(17.1,15));


(DecimalPrecision.round(0.014999999999999999, 2)) // 返回 0.02
@KFish DecimalPrecision.ceil(17,0); // 18DecimalPrecision.ceil(17,1); // 17.1
@KFish DecimalPrecision.ceil(-5.12, 1); // -5.2DecimalPrecision.floor(-5.12, 1); // -5.1
无论采用何种方法,重要的是人们要明白总会有一些边缘情况无法正确评估。例如,在您的版本或我的版本中,此 DecimalPrecision.ceil(10000000000000000.00111, 4) 会产生此结果 10000000000000000,而在技术上它应该是 10000000000000000.0012。由于指数符号的处理,我会推荐你的版本而不是我的版本,但人们需要意识到,充其量只会降低错误的概率。
“编辑”、“更新”等不属于本帖。应该改成现在写的样子。 修订历史记录永远保留以前的版本。参见例如 Is it recommended to notify the answer "Edits" with an heading followed by the edit content?When is "EDIT"/"UPDATE" appropriate in a post?Why are new editors discouraged & not given an opportunity to explain/defend?
b
bigpotato

最简单的方法:

+num.toFixed(2)

它将其转换为字符串,然后再转换回整数/浮点数。


感谢这个最简单的答案。但是,+num 中的 '+' 是什么?在十进制 val 以字符串形式出现的情况下,它对我不起作用。我做到了:(num * 1).toFixed(2)。
@momo 只需将 toFixed() 的参数更改为 3。所以它会是 +num.toFixed(3)。这是按预期方式工作的,1.005 舍入为 1.00,等于 1
@Edmund 它应该返回 1.01,而不是 1.00
这是 user3711536's answer 的副本——尽管这个有一些(如果不充分的话)解释。