【问题标题】:How to round in javascript like PHP do如何像 PHP 一样在 javascript 中进行舍入
【发布时间】:2025-12-15 13:05:02
【问题描述】:

我正在尝试以与 PHP 中相同的方式在 Javascript 中对浮点数进行舍入;但是我不能让两种语言都以同样的方式轮到下面的数字:6.404999999999999

当我使用 PHP 回合时,我得到:6.41但是当我尝试使用 Javascript 回合时,我总是得到 6.40

信息:正确答案是https://*.com/a/54721202/4359029

我的 Javascript 尝试:

尝试 #1:

module.exports = function round (value, precision, mode) {
  var m, f, isHalf, sgn // helper variables
  // making sure precision is integer
  precision |= 0
  m = Math.pow(10, precision)
  value *= m
  // sign of the number
  sgn = (value > 0) | -(value < 0)
  isHalf = value % 1 === 0.5 * sgn
  f = Math.floor(value)

  if (isHalf) {
    switch (mode) {
      case 'PHP_ROUND_HALF_DOWN':
      // rounds .5 toward zero
        value = f + (sgn < 0)
        break
      case 'PHP_ROUND_HALF_EVEN':
      // rouds .5 towards the next even integer
        value = f + (f % 2 * sgn)
        break
      case 'PHP_ROUND_HALF_ODD':
      // rounds .5 towards the next odd integer
        value = f + !(f % 2)
        break
      default:
      // rounds .5 away from zero
        value = f + (sgn > 0)
    }
  }

  return (isHalf ? value : Math.round(value)) / m
}

摘自:http://locutus.io/php/math/round/

尝试 #2:

round(decimal: number, decimalPoints: number): number{
    let roundedValue = Math.round(decimal * Math.pow(10, decimalPoints)) / Math.pow(10, decimalPoints);

    console.log(`Rounded ${decimal} to ${roundedValue}`);
    return roundedValue;
}

摘自:https://*.com/a/50918962/4359029


我尝试了其他解决方案...但没有成功。

有人能告诉我如何让 Javascript 的四舍五入像 PHP 一样吗?

你能告诉我为什么在我解释的情况下它们以不同的方式工作吗?

【问题讨论】:

  • 这可能是因为 PHP 确实具有数字的准确二进制表示,并且知道该数字实际上是 6.405,但无法以十进制准确显示。 this is a good read about this 问题在于,很可能当您将该数字的十进制表示发送到 JavaScript 时,准确的二进制表示会丢失,并且 JavaScript 必须处理嘈杂的数据。我怀疑除了将操作发送到 JavaScript 并让它从头开始计算之外还有什么可做的

标签: javascript php math rounding


【解决方案1】:

我认为最佳答案是下一个:

function roundLikePHP(num, dec){
  var num_sign = num >= 0 ? 1 : -1;
  return parseFloat((Math.round((num * Math.pow(10, dec)) + (num_sign * 0.0001)) / Math.pow(10, dec)).toFixed(dec));
}

我用1.015 尝试了其他解决方案,但没有按预期工作。

这个解决方案效果很好,就像 PHP 回合一样,我尝试了所有的数字。

【讨论】:

  • 最佳答案! :) 谢谢@tomloprod
  • 虽然此函数与 php 函数很接近,但在某些情况下仍会返回不同的结果。例如 roundLikePHP(0.49999,0) = 1 而在 php 中 round(0.49999) = 0 .
  • @Andyba 嗨。这个问题只发生在四舍五入到小数点为0时,所以至少在我的情况下,它不会影响我
  • @tomloprod 不完全是:roundLikePHP(0.004999999,2) = 0.01 而在 php 中 round(0.004999999,2) = 0
【解决方案2】:

你可以使用toPrecision函数

它将被提供的precision 四舍五入。这里我用4四舍五入得到6.405,然后用3四舍五入得到6.41

parseFloat((6.404999999999999).toPrecision(4)).toPrecision(3);

console.log(parseFloat((6.404999999999999).toPrecision(4)).toPrecision(3));

【讨论】:

  • 您能否解释一下为什么您的解决方案不适用于下一个数字:1.015?这轮到 1.01 而不是 1.02
【解决方案3】:

你可以这样做:

function roundToXDigits(value, digits)
{
    if (!digits) {
        digits = 2;
    }

    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);

    return value
}

var num = roundToXDigits(6.404999999999999, 3); //creates 6.405

console.log(roundToXDigits(num, 2)); //creates 6.41

问题是,JavaScript 技术上 没有错。 6.4049 -> 当你四舍五入时变成 6.405(到 2dp 是 6.40),这就是它没有按预期工作的原因。您必须运行函数 两次 到第 405 -> 41 轮。

来源:JavaScript math, round to two decimal places

^^ Bryce 答案的扩展用法。

【讨论】:

  • @tomloprod 没有问题,希望对您有所帮助:)
  • treyBake 效果很好!我认为它类似于@C2486 的答案。伙计们,您认为哪种解决方案最好?
  • @tomloprod :深入探索任何方法总是好的,但最佳实践是使用任何语言或框架提供的内置方法。很高兴看到toPrecision 的详细代码为roundToXDigits。如果任何版本的浏览器都不支持内置方法,这个roundToXDigits 方法会很棒。
  • @treyBake 您能否解释一下为什么您的解决方案不适用于下一个数字:1.015?这轮到1.01 而不是1.02
  • @tomloprod 此解决方案不适用于 1.015,因为在 JS 1.015*100=101.49999999999999 中
【解决方案4】:

你可以试试

console.log(Number(n.toFixed(3)).toFixed(2));

例如。

var n = 6.404999999999999;
console.log(n.toFixed(2)); //=> 6.40
console.log(n.toFixed(3)); //=> 6.405

【讨论】:

  • @RokoC.Buljan,PHP 和 javascript 中的 round 方法有根本的区别。但是根据轮函数的基本定义,值等于 JavaScript 的结果。
  • 这个怎么样,console.log(Number(n.toFixed(3)).toFixed(2));
最近更新 更多