舍入到最多2位小数(仅在必要时)

时间:2012-08-06 17:17:48

标签: javascript decimal rounding decimal-point

我想最多舍入2位小数,但只在必要时

输入:

10
1.7777777
9.1

输出:

10
1.78
9.1

我怎样才能在JavaScript中执行此操作?

79 个答案:

答案 0 :(得分:2825)

使用Math.round(num * 100) / 100

答案 1 :(得分:2664)

如果值是文本类型:

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是更好的解决方案。 但事实并非如此!在某些情况下,它会 NOT 正确舍入:

Math.round(1.005 * 1000)/1000 // Returns 1 instead of expected 1.01!
在某些情况下,

toFixed()也会 NOT 正确舍入(在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实际上就像浮动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);
  }
}

https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview

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

答案 2 :(得分:391)

您可以使用

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

我在MDN上发现了这一点。他们的方式避免了1.005 mentioned的问题。

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

答案 3 :(得分:129)

MarkG的答案是正确的。这是任意数量小数位的通用扩展名。

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');
  });
})

答案 4 :(得分:77)

可以使用.toFixed(NumberOfDecimalPlaces)

var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23

答案 5 :(得分:62)

精确的舍入方法。资料来源:Mozilla

(function(){

    /**
     * Decimal adjustment of a number.
     *
     * @param   {String}    type    The type of adjustment.
     * @param   {Number}    value   The number.
     * @param   {Integer}   exp     The exponent (the 10 logarithm of the adjustment base).
     * @returns {Number}            The adjusted value.
     */
    function decimalAdjust(type, value, exp) {
        // If the exp is undefined or zero...
        if (typeof exp === 'undefined' || +exp === 0) {
            return Math[type](value);
        }
        value = +value;
        exp = +exp;
        // If the value is not a number or the exp is not an integer...
        if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
            return NaN;
        }
        // Shift
        value = value.toString().split('e');
        value = Math[type](+(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));
    }

    // Decimal round
    if (!Math.round10) {
        Math.round10 = function(value, exp) {
            return decimalAdjust('round', value, exp);
        };
    }
    // Decimal floor
    if (!Math.floor10) {
        Math.floor10 = function(value, exp) {
            return decimalAdjust('floor', value, exp);
        };
    }
    // Decimal ceil
    if (!Math.ceil10) {
        Math.ceil10 = function(value, exp) {
            return decimalAdjust('ceil', value, exp);
        };
    }
})();

示例:

// Round
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
// Floor
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Ceil
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50

答案 6 :(得分:61)

考虑.toFixed().toPrecision()

http://www.javascriptkit.com/javatutors/formatnumber.shtml

答案 7 :(得分:56)

此处找到的答案都不正确。 @stinkycheeseman要求四舍五入,你们都把这个数字四舍五入。

要整理,请使用:

Math.ceil(num * 100)/100;

答案 8 :(得分:50)

您应该使用:

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之间没有数字。

修改

正如评论中所提到的,让我们澄清一点:只有当round的值是算术运算的结果时才添加Number.EPSILON,因为它可以吞下一些浮点误差delta。

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

答案 9 :(得分:44)

这是一种简单的方法:

Math.round(value * 100) / 100

你可能希望继续为你做一个单独的功能:

function roundToTwo(value) {
    return(Math.round(value * 100) / 100);
}

然后你只需传入值。

您可以通过添加第二个参数来增强它以舍入到任意数量的小数。

function myRound(value, places) {
    var multiplier = Math.pow(10, places);

    return (Math.round(value * multiplier) / multiplier);
}

答案 10 :(得分:36)

对我来说Math.round()没有给出正确答案。我发现toFixed(2)效果更好。 以下是两者的示例:

console.log(Math.round(43000 / 80000) * 100); // wrong answer

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer

答案 11 :(得分:36)

+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12

答案 12 :(得分:33)

使用此功能Number(x).toFixed(2);

答案 13 :(得分:33)

2017
只需使用原生代码.toFixed()

number = 1.2345;
number.toFixed(2) // "1.23"

如果您需要严格并在需要时添加数字,则可以使用replace

number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');

答案 14 :(得分:31)

尝试轻量级解决方案:

function round(x, digits){
  return parseFloat(x.toFixed(digits))
}

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222

答案 15 :(得分:28)

有几种方法可以做到这一点。像我这样的人,Lodash的变种

function round(number, precision) {
    var pair = (number + 'e').split('e')
    var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
    pair = (value + 'e').split('e')
    return +(pair[0] + 'e' + (+pair[1] - precision))
}

<强>用法:

round(0.015, 2) // 0.02
round(1.005, 2) // 1.01

如果你的项目使用jQuery或lodash,你也可以在库中找到合适的round方法。

更新1

我删除了变体n.toFixed(2),因为它不正确。谢谢@ avalanche1

答案 16 :(得分:22)

MarkG和Lavamantis提供了一个比被接受的解决方案更好的解决方案。很遗憾他们没有得到更多的赞成!

这是我用来解决浮点小数问题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

答案 17 :(得分:21)

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

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

答案 18 :(得分:20)

如果您使用的是lodash库,则可以使用lodash的圆形方法,如下所示。

_.round(number, precision)

例如:

_.round(1.7777777, 2) = 1.78

答案 19 :(得分:16)

var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2)这里2是我们想要对这个数字进行舍入的位数。

答案 20 :(得分:16)

这可能会对您有所帮助:

var result = (Math.round(input*100)/100);

了解更多信息,您可以查看此链接

Math.round(num) vs num.toFixed(0) and browser inconsistencies

答案 21 :(得分:13)

最简单的方法:

+num.toFixed(2)

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

答案 22 :(得分:13)

使用类似的东西 &#34; parseFloat(parseFloat(值).toFixed(2))&#34;

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1

答案 23 :(得分:12)

这是一个原型方法:

Number.prototype.round = function(places){
    places = Math.pow(10, places); 
    return Math.round(this * places)/places;
}

var yournum = 10.55555;
yournum = yournum.round(2);

答案 24 :(得分:12)

它可能适合你,

Math.round(num * 100)/100;

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

答案 25 :(得分:11)

自ES6以来,有一个“适当的”&#39;方式(没有覆盖静态和创建变通方法)通过using toPrecision

执行此操作

&#13;
&#13;
var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));

var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));

var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));
&#13;
&#13;
&#13;

答案 26 :(得分:11)

通常,通过缩放来完成舍入:round(num / p) * p

使用指数表示法正确处理+ ve数字的舍入。 但是,此方法无法正确舍入边缘情况。

&#13;
&#13;
function round(num, precision = 2) {
	var scaled = Math.round(num + "e" + precision);
	return Number(scaled + "e" + -precision);
}

// testing some edge cases
console.log( round(1.005, 2) );  // 1.01 correct
console.log( round(2.175, 2) );  // 2.18 correct
console.log( round(5.015, 2) );  // 5.02 correct

console.log( round(-1.005, 2) );  // -1    wrong
console.log( round(-2.175, 2) );  // -2.17 wrong
console.log( round(-5.015, 2) );  // -5.01 wrong
&#13;
&#13;
&#13;

这里也是我写的一个函数正确地进行算术舍入。你可以自己测试一下。

&#13;
&#13;
/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct
&#13;
&#13;
&#13;

答案 27 :(得分:10)

要不处理多个0,请使用以下变体:

Math.round(num * 1e2) / 1e2

答案 28 :(得分:9)

如果你碰巧已经在使用d3库,那么他们有一个强大的数字格式库:https://github.com/mbostock/d3/wiki/Formatting

特此舍入在这里:https://github.com/mbostock/d3/wiki/Formatting#d3_round

在您的情况下,答案是:

> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1

答案 29 :(得分:8)

更简单的ES6方式是

const round = (x, n) => 
  parseFloat(Math.round(x * Math.pow(10, n)) / Math.pow(10, n)).toFixed(n);

此模式还返回要求的精度。

例如:

round(44.7826456, 4)  // yields 44.7826
round(78.12, 4)       // yields 78.1200

答案 30 :(得分:8)

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

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

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

答案 31 :(得分:7)

基于choosen answerupvoted comment的相同问题:

Math.round((num + 0.00001) * 100) / 100

这对这两个示例都适用:

Math.round((1.005 + 0.00001) * 100) / 100

Math.round((1.0049 + 0.00001) * 100) / 100

答案 32 :(得分:7)

我将再添加一种方法。

<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>

<select id="choose_package" >
    <option value="Sliver"> Sliver</option>
    <option value="Gold"> Gold</option>
    <option value="Broze"> Broze</option>
    <option value="Limited"> Limited</option>
</select>
<div class="package_limit">
</div>

number = 16.6666666; console.log(parseFloat(number.toFixed(2))); "16.67" number = 16.6; console.log(parseFloat(number.toFixed(2))); "16.6" number = 16; console.log(parseFloat(number.toFixed(2))); "16" 返回一个带有2个小数点的字符串,可能是也可能不是尾随零。执行.toFixed(2)将消除那些尾随零。

答案 33 :(得分:7)

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

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

答案 34 :(得分:7)

如果想舍入,简单的解决方案是使用lodash的ceil函数。

https://lodash.com/docs/4.17.10#ceil

_.round(6.001,2)

给出6

_.ceil(6.001, 2);

给出6.01

_.ceil(37.4929,2);

给出37.5

_.round(37.4929,2);

给出37.49

答案 35 :(得分:7)

  

parseFloat(“ 1.555”)。toFixed(2); //返回1.55,而不是1.56。

1.55是绝对正确的结果,因为计算机中不存在1.555的精确表示。如果读数为1.555,则四舍五入为最接近的可能值= 1.55499999999999994(64位浮点型)。并将此数字四舍五入到toFixed(2)将得出1.55。

如果输入为1.55499999999999,则此处提供的所有其他功能都会给出错误结果。

解决方案:在扫描之前将数字“ 5”附加到四舍五入(更精确的是:从0舍入)。仅在数字确实是浮点数(有小数点)时才执行此操作。

parseFloat("1.555"+"5").toFixed(2); // Returns 1.56

答案 36 :(得分:6)

另一种方法是使用库。为什么不lodash

const _ = require("lodash")
const roundedNumber = _.round(originalNumber, 2)

答案 37 :(得分:6)

我知道有很多答案,但大多数答案在某些特定情况下都有副作用。

没有任何副作用的最简单和最短的解决方案如下:

Number((2.3456789).toFixed(2)) // 2.35

它正确舍入并返回数字而不是字符串

console.log(Number((2.345).toFixed(2)))  // 2.35
console.log(Number((2.344).toFixed(2)))  // 2.34
console.log(Number((2).toFixed(2)))      // 2
console.log(Number((-2).toFixed(2)))     // -2
console.log(Number((-2.345).toFixed(2))) // -2.35

console.log(Number((2.345678).toFixed(3))) // 2.346

答案 38 :(得分:5)

这对我有用(TypeScript):

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;
}

// Sample output:
Rounded 18.339840000000436 to 18.34
Rounded 52.48283999999984 to 52.48
Rounded 57.24612000000036 to 57.25
Rounded 23.068320000000142 to 23.07
Rounded 7.792980000000398 to 7.79
Rounded 31.54157999999981 to 31.54
Rounded 36.79686000000004 to 36.8
Rounded 34.723080000000124 to 34.72
Rounded 8.4375 to 8.44
Rounded 15.666960000000074 to 15.67
Rounded 29.531279999999924 to 29.53
Rounded 8.277420000000006 to 8.28

答案 39 :(得分:4)

我查看了该帖子的每个答案。 这是我对此事的看法:

const nbRounds = 7;
const round = (x, n=2) => {
    const precision = Math.pow(10, n)
    return Math.round((x+Number.EPSILON) * precision ) / precision;
}

new Array(nbRounds).fill(1).forEach((_,i)=> {
    console.log("round(1.00083899, ",i+1,") > ", round(1.00083899, i+1))
    console.log("round(1.83999305, ",i+1,") > ", round(1.83999305, i+1))
})

答案 40 :(得分:4)

下面是一个简单的通用舍入函数:

步骤是:

  1. 使用 Math.pow(10,places)将数字乘以(小数点后位数的10的幂)。
  2. 使用 Math.Round 将结果四舍五入为整数。
  3. 将结果除以(10到小数位数的幂) Math.pow(10,places)

示例:

数字是:1.2375 四舍五入到小数点后三位

  1. 1.2375 *(10 ^ 3)==> 1.2375 * 1000 = 1237.5
  2. 舍入为整数==> 1238
  3. 将1238除以(10 ^ 3)==> 1238/1000 = 1.238

(注意:10 ^ 3表示Math.pow(10,3))。

 function numberRoundDecimal(v,n) {
 return Math.round((v+Number.EPSILON)*Math.pow(10,n))/Math.pow(10,n)}


// ------- tests --------
console.log(numberRoundDecimal(-0.024641163062896567,3))  // -0.025
console.log(numberRoundDecimal(0.9993360575508052,3))     // 0.999
console.log(numberRoundDecimal(1.0020739645577939,3))     // 1.002
console.log(numberRoundDecimal(0.975,0))                  // 1
console.log(numberRoundDecimal(0.975,1))                  // 1
console.log(numberRoundDecimal(0.975,2))                  // 0.98
console.log(numberRoundDecimal(1.005,2))                  // 1.01

答案 41 :(得分:4)

以下是最简短的答案:

function round(num, decimals) {
        var n = Math.pow(10, decimals);
        return Math.round( (n * num).toFixed(decimals) )  / n;
};

这也会处理示例情况1.005,它将返回1.01。

答案 42 :(得分:4)

我正在构建一个简单的tipCalculator,并且这里有很多答案似乎使问题变得更加复杂。因此,我发现总结问题是真正回答这个问题的最佳方法

如果要创建一个舍入的十进制数字,请首先调用toFixed(# of decimal places you want to keep),然后将其包装在Number()中

所以最终结果:

let amountDue = 286.44;
tip = Number((amountDue * 0.2).toFixed(2));
console.log(tip)  // 57.29 instead of 57.288

答案 43 :(得分:4)

尝试使用jQuery .number plug-in

var number = 19.8000000007;
var res = 1 * $.number(number, 2);

答案 44 :(得分:3)

你也可以覆盖Math.round函数来进行舍入校正并为小数添加一个参数并使用它:Math.round(Number,Decimals)。请记住,这会覆盖内置组件Math.round并为其提供另一个属性,原则是。

var round = Math.round;
Math.round = function (value, decimals) {
  decimals = decimals || 0;
  return Number(round(value + 'e' + decimals) + 'e-' + decimals);
}

然后你就可以这样简单地使用它:

Math.round(1.005, 2);

https://jsfiddle.net/k5tpq3pd/3/

答案 45 :(得分:3)

要以小数位pos(包括无小数)进行舍入,请执行Math.round(num * Math.pow(10,pos)) / Math.pow(10,pos)

var console = {
 log: function(s) {
  document.getElementById("console").innerHTML += s + "<br/>"
 }
}
var roundDecimals=function(num,pos) {
 return (Math.round(num * Math.pow(10,pos)) / Math.pow(10,pos) );
}
//https://en.wikipedia.org/wiki/Pi
var pi=3.14159265358979323846264338327950288419716939937510;
for(var i=2;i<15;i++) console.log("pi="+roundDecimals(pi,i));
for(var i=15;i>=0;--i) console.log("pi="+roundDecimals(pi,i));
<div id="console" />

答案 46 :(得分:3)

这是我想出的一个“向上”的功能。我使用双Math.round来补偿JavaScript的不准确乘法,因此1.005将正确舍入为1.01。

function myRound(number, decimalplaces){
    if(decimalplaces > 0){
        var multiply1 = Math.pow(10,(decimalplaces + 4));
        var divide1 = Math.pow(10, decimalplaces);
        return Math.round(Math.round(number * multiply1)/10000 )/divide1;
    }
    if(decimalplaces < 0){
        var divide2 = Math.pow(10, Math.abs(decimalplaces));
        var multiply2 = Math.pow(10, Math.abs(decimalplaces));
        return Math.round(Math.round(number / divide2) * multiply2);
    }
    return Math.round(number);
}

答案 47 :(得分:3)

我为自己写了以下一系列功能。也许它对你也有帮助。

function float_exponent(number) {
    exponent = 1;
    while (number < 1.0) {
        exponent += 1
        number *= 10
    }
    return exponent;
}
function format_float(number, extra_precision) {
    precision = float_exponent(number) + (extra_precision || 0)
    return number.toFixed(precision).split(/\.?0+$/)[0]
}

用法:

format_float(1.01); // 1
format_float(1.06); // 1.1
format_float(0.126); // 0.13
format_float(0.000189); // 0.00019

对于你的情况:

format_float(10, 1); // 10
format_float(9.1, 1); // 9.1
format_float(1.77777, 1); // 1.78

答案 48 :(得分:2)

当我想始终取整到某个小数时,这对我来说效果很好。关键是我们将始终使用Math.ceil函数进行取整。

如果需要,您可以有条件地选择天花板或地板。

 public Job myJob() {
    Step extract = extractorStep();
    Step process = filesProcessStep();
    Step cleanup = cleanupStep();

    return jobBuilderFactory.get("my-job")
          .start(echo("Starting batch job"))

          .next(extract).on(ExitStatus.FAILED.getExitCode()).to(cleanup)
          .from(extract).on("*").to(process)

          .next(process).on(ExitStatus.FAILED.getExitCode()).to(cleanup)
          .from(process).on("*").to(cleanup)

          .next(echo("End batch job"))
          .end()
          .build();
  }

答案 49 :(得分:2)

在经过所有可能的方式的各种迭代以达到真正准确的十进制舍入精度之后,很明显,最准确和有效的解决方案是使用Number.EPSILON。这为浮点数学精度问题提供了一个真正的数学解决方案。可以很容易地对其进行填充,如下所示:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON以支持所有剩余的IE用户(然后也许我们应该停止这样做)。

改编自此处提供的解决方案:https://stackoverflow.com/a/48850944/6910392

简单的解决方案,可提供精确的十进制舍入,下限和上限,并带有可选的precision变量,而无需添加整个库。

message

答案 50 :(得分:2)

从现有的答案中我发现了另一个似乎很有效的解决方案,它也适用于发送字符串并消除尾随零。

function roundToDecimal(string, decimals) {
    return parseFloat(parseFloat(string).toFixed(decimals));
}

如果你发送了一些公牛,它就不会考虑到这一点......比如&#34; apa&#34;虽然。或者它可能会抛出一个错误,我认为这是正确的方法,它隐藏了应该修复的错误(通过调用函数)。

答案 51 :(得分:2)

数学下限和舍入definitions

enter image description here

带领我们

let round= x=> ( x+0.005 - (x+0.005)%0.01 +'' ).replace(/(\...)(.*)/,'$1');

// for case like 1.384 we need to use regexp to get only 2 digits after dot
// and cut off machine-error (epsilon)

console.log(round(10));
console.log(round(1.7777777));
console.log(round(1.7747777));
console.log(round(1.384));

答案 52 :(得分:2)

将类型保留为整数,以便以后进行排序或其他数学运算:

Math.round(1.7777777 * 100)/100
  

1.78

// Round up!
Math.ceil(1.7777777 * 100)/100 
  

1.78

// Round down!
Math.floor(1.7777777 * 100)/100
  

1.77

或转换为字符串:

(1.7777777).toFixed(2)
  

“ 1.77”

答案 53 :(得分:2)

对此稍有不同,如果您需要将货币金额的格式设置为全部货币金额或带有小数货币部分的金额。

例如:

1应该输出$ 1

1.1应该输出$ 1.10

1.01应该输出$ 1.01

假设金额是数字:

const formatAmount = (amount) => amount % 1 === 0 ? amount : amount.toFixed(2);

如果数量不是数字,则使用parseFloat(amount)将其转换为数字。

答案 54 :(得分:1)

此看似简单的任务面临的最大挑战是,即使输入包含最小的舍入误差(不提及在计算中会发生的误差),我们仍希望它产生心理上预期的结果。如果我们知道实际结果正好是1.005,那么即使将1.005舍入为四舍五入的错误也需要进行大的计算,但即使将1.005舍入为两位数也可以得出1.01。

在处理floor()而不是round()时,问题变得更加明显。例如,当在33.3点后面的最后两位数字处删除所有内容时,我们肯定不会期望结果为33.29,但这就是发生的情况:

console.log(Math.floor(33.3 * 100) / 100)

在简单的情况下,解决方案是对字符串而不是浮点数进行计算,从而完全避免舍入错误。但是,此选项在第一个非平凡的数学运算(包括大多数除法)时会失败,并且速度很慢。

在对浮点数进行运算时,解决方案是引入一个参数,该参数命名我们愿意偏离实际计算结果的量,以便输出心理预期结果。

var round = function(num, digits = 2, compensateErrors = 2) {
  if (num < 0) {
    return -this.round(-num, digits, compensateErrors);
  }
  const pow = Math.pow(10, digits);
  return (Math.round(num * pow * (1 + compensateErrors * Number.EPSILON)) / pow);
}

/* --- testing --- */

console.log("Edge cases mentioned in this thread:")
var values = [ 0.015, 1.005, 5.555, 156893.145, 362.42499999999995, 1.275, 1.27499, 1.2345678e+2, 2.175, 5.015, 58.9 * 0.15 ];
values.forEach((n) => {
  console.log(n + " -> " + round(n));
  console.log(-n + " -> " + round(-n));
});

console.log("\nFor numbers which are so large that rounding cannot be performed anyway within computation precision, only string-based computation can help.")
console.log("Standard: " + round(1e+19));
console.log("Compensation = 1: " + round(1e+19, 2, 1));
console.log("Effectively no compensation: " + round(1e+19, 2, 0.4));

注意:Internet Explorer不知道Number.EPSILON。如果您仍然不愿意支持它,可以使用填充片,也可以只为该特定浏览器系列定义常量。

答案 55 :(得分:1)

我已经阅读了所有答案,类似问题的答案以及最“好的”解决方案的复杂性,这并不令我满意。我不想放置一个巨大的圆形函数集,也不想放置一个很小的圆形函数集,但是在科学计数法上却失败了。因此,我想出了这个功能。在我遇到的情况下可能会有所帮助:

--recursive

我没有进行任何性能测试,因为我将其称为仅用于更新应用程序的UI。该功能可提供以下结果以进行快速测试:

function round(num, dec) {
   const [sv, ev] = num.toString().split('e');
   return Number(Number(Math.round(parseFloat(sv + 'e' + dec)) + 'e-' + dec) + 'e' + (ev || 0));
}

这对我来说足够了。

答案 56 :(得分:1)

这是我解决这个问题的方法:

function roundNumber(number, precision = 0) {
var num = number.toString().replace(",", "");
var integer, decimal, significantDigit;

if (num.indexOf(".") > 0 && num.substring(num.indexOf(".") + 1).length > precision && precision > 0) {
    integer = parseInt(num).toString();
    decimal = num.substring(num.indexOf(".") + 1);
    significantDigit = Number(decimal.substr(precision, 1));

    if (significantDigit >= 5) {
        decimal = (Number(decimal.substr(0, precision)) + 1).toString();
        return integer + "." + decimal;
    } else {
        decimal = (Number(decimal.substr(0, precision)) + 1).toString();
        return integer + "." + decimal;
    }
}
else if (num.indexOf(".") > 0) {
    integer = parseInt(num).toString();
    decimal = num.substring(num.indexOf(".") + 1);
    significantDigit = num.substring(num.length - 1, 1);

    if (significantDigit >= 5) {
        decimal = (Number(decimal) + 1).toString();
        return integer + "." + decimal;
    } else {            
        return integer + "." + decimal;
    }
} 

return number;
}

答案 57 :(得分:1)

问题是将小数点后两位取整。

不要让这个复杂的修改原型链等。

这是一种解决方案

let round2dec = num => Math.round(num * 100) / 100; 

console.log(round2dec(1.77));
console.log(round2dec(1.774));
console.log(round2dec(1.777));
console.log(round2dec(10));

答案 58 :(得分:1)

根据已在评论中给出的答案以及指向http://jsfiddle.net/AsRqx/的链接 跟随一个人对我非常有用。

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

function N(num, places) 
  { return +(Math.round(num + "e+" + places)  + "e-" + places);
  }

C(1.005);

N(1.005,0);
N(1.005,1); //up to 1 decimal places
N(1.005,2); //up to 2 decimal places
N(1.005,3); //up to 3 decimal places

答案 59 :(得分:1)

在节点环境中,我只使用roundTo模块:

const roundTo = require('round-to');
...
roundTo(123.4567, 2);

// 123.46

答案 60 :(得分:1)

从我在precisionRound上发现的MDN上提出的示例开始(该事件为1.005 returs 1而不是1.01),我编写了一个自定义的 precisionRound 来管理随机精度数,1.005返回1.01。

这是功能:

function precisionRound(number, precision)
{
  if(precision < 0)
  {
    var factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  }
  else
    return +(Math.round(number + "e+"+precision)  + "e-"+precision);
}

console.log(precisionRound(1234.5678, 1));  // output: 1234.6
console.log(precisionRound(1234.5678, -1)); // output: 1230
console.log(precisionRound(1.005, 2));      // output: 1.01
console.log(precisionRound(1.0005, 2));     // output: 1
console.log(precisionRound(1.0005, 3));     // output: 1.001
console.log(precisionRound(1.0005, 4));     // output: 1.0005

对于TypeScript:

public static precisionRound(number: number, precision: number)
{
  if (precision < 0)
  {
    let factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  }
  else
    return +(Math.round(Number(number + "e+" + precision)) +
      "e-" + precision);
}

答案 61 :(得分:1)

我只是想根据前面提到的答案分享我的方法:

让我们创建一个函数,将任何给定的数值舍入到给定的小数位数:

function roundWDecimals(n, decimals) {
    if (!isNaN(parseFloat(n)) && isFinite(n)) {
        if (typeof(decimals) == typeof(undefined)) {
            decimals = 0;
        }
        var decimalPower = Math.pow(10, decimals);
        return Math.round(parseFloat(n) * decimalPower) / decimalPower;
    }
    return NaN;
}

并介绍一个新的&#34; round&#34;数字原型的方法:

Object.defineProperty(Number.prototype, 'round', {
    enumerable: false,
    value: function(decimals) {
        return roundWDecimals(this, decimals);
    }
});

你可以测试一下:

&#13;
&#13;
function roundWDecimals(n, decimals) {
    if (!isNaN(parseFloat(n)) && isFinite(n)) {
        if (typeof(decimals) == typeof(undefined)) {
            decimals = 0;
        }
        var decimalPower = Math.pow(10, decimals);
        return Math.round(parseFloat(n) * decimalPower) / decimalPower;
    }
    return NaN;
}
Object.defineProperty(Number.prototype, 'round', {
    enumerable: false,
    value: function(decimals) {
        return roundWDecimals(this, decimals);
    }
});

var roundables = [
    {num: 10, decimals: 2},
    {num: 1.7777777, decimals: 2},
    {num: 9.1, decimals: 2},
    {num: 55.55, decimals: 1},
    {num: 55.549, decimals: 1},
    {num: 55, decimals: 0},
    {num: 54.9, decimals: 0},
    {num: -55.55, decimals: 1},
    {num: -55.551, decimals: 1},
    {num: -55, decimals: 0},
    {num: 1.005, decimals: 2},
    {num: 1.005, decimals: 2},
    {num: 19.8000000007, decimals: 2},
  ],
  table = '<table border="1"><tr><th>Num</th><th>Decimals</th><th>Result</th></tr>';
$.each(roundables, function() {
  table +=
    '<tr>'+
      '<td>'+this.num+'</td>'+
      '<td>'+this.decimals+'</td>'+
      '<td>'+this.num.round(this.decimals)+'</td>'+
    '</tr>'
  ;
});
table += '</table>';
$('.results').append(table);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="results"></div>
&#13;
&#13;
&#13;

答案 62 :(得分:1)

此功能对我有用。您只需输入数字和要四舍五入的位置,即可轻松完成所需的操作。

round(source,n) {
 let places = Math.pow(10,n);

 return Math.round(source * places) / places;
}

答案 63 :(得分:1)

所有浏览器和精度的通用答案:

function round(num, places) {
      if(!places){
       return Math.round(num);
      }

      var val = Math.pow(10, places);
      return Math.round(num * val) / val;
}

round(num, 2);

答案 64 :(得分:1)

只是为了记录,如果要舍入的数字和数字足够大,理论上缩放方法可以返回Infinity。在JavaScript中不应该是一个问题,因为最大数字是1.7976931348623157e + 308,但是如果你正在使用非常大的数字或许多小数位,你可以试试这个函数:

&#13;
&#13;
Number.prototype.roundTo = function(digits)
{
    var str = this.toString();
    var split = this.toString().split('e');
    var scientific = split.length > 1;
    var index;
    if (scientific)
    {
        str = split[0];
        var decimal = str.split('.');
        if (decimal.length < 2)
            return this;
        index = decimal[0].length + 1 + digits;
    }
    else
        index = Math.floor(this).toString().length + 1 + digits;
    if (str.length <= index)
        return this;
    var digit = str[index + 1];
    var num = Number.parseFloat(str.substring(0, index));
    if (digit >= 5)
    {
        var extra = Math.pow(10, -digits);
        return this < 0 ? num - extra : num + extra;
    }
    if (scientific)
        num += "e" + split[1];
    return num;
}
&#13;
&#13;
&#13;

答案 65 :(得分:0)

建议的答案虽然通常是正确的,但并未考虑传递数字的精度,这在原始问题中并未表示为要求,但在科学应用中3不同于3.00时可能是要求(对于例如),因为小数位数代表已获取值的仪器的精度或计算的精度。 实际上,建议的答案将3.001舍入为3,同时通过保持有关数字精度的信息应为3.00

下面的函数考虑了这一点

function roundTo(value, decimal) {

    let absValue = Math.abs(value);
    let int = Math.floor(absValue).toString().length;
    let dec = absValue.toString().length - int;
    dec -= (Number.isInteger(absValue) ? 0 : 1);
    return value.toPrecision(int + Math.min(dec, decimal));
  
}

答案 66 :(得分:0)

this answer的轻微修改似乎效果很好。

功能

regexpr("\\{(\\S|\\s)+\\}",txt,perl = T) %>% regmatches(x=txt)
#[1] "{a:b, c:d}"

用法

function roundToStep(value, stepParam) {
   var step = stepParam || 1.0;
   var inv = 1.0 / step;
   return Math.round(value * inv) / inv;
}

答案 67 :(得分:0)

使用指数表示法可以避免舍入问题。

public static roundFinancial(amount: number, decimals: number) {
    return Number(Math.round(Number(`${amount}e${decimals}`)) + `e-${decimals}`);
}

答案 68 :(得分:0)

有一种适用于所有数字的解决方案,请尝试一下。表达式如下。

Math.round((num + 0.00001) * 100) / 100. Try Math.round((1.005 + 0.00001) * 100) / 100 and Math.round((1.0049 + 0.00001) * 100) / 100

我最近测试了所有可能的解决方案,并在尝试了近10次之后终于达到了输出。这是计算过程中出现的问题的屏幕截图, Screen Capture

转到amount字段,它几乎返回无限。我尝试了toFixed()方法,但在某些情况下无法正常工作(例如尝试使用PI),最后得出了上面给出的解决方案。

答案 69 :(得分:0)

快速帮助程序功能,其中rounging是您的默认舍入: let rounding = 4;

let round=(number)=>{ let multiply=Math.pow(10,rounding);  return Math.round(number*multiply)/multiply};

console.log(round(0.040579431));

=> 0.0406

答案 70 :(得分:0)

我创建了此函数,用于四舍五入一个数字。该值可以是字符串(例如'1.005')或数字1.005(默认情况下为1),如果您将小数指定为2,则结果将为1.01

round(value: string | number, decimals: number | string = "0"): number | null {
    return +( Math.round(Number(value + "e+"+decimals)) + "e-" + decimals);
}

用法:回合(1.005,2)// 1.01 要么 用法:round('1.005',2)//1.01

答案 71 :(得分:0)

我发现这适用于所有用例:

const round = (value, decimalPlaces = 0) => {
    const multiplier = Math.pow(10, decimalPlaces);
    return Math.round(value * multiplier + Number.EPSILON) / multiplier;
};

请记住,这是ES6。相当于ES5。虽然这样很容易编码,所以我不想添加它。

答案 72 :(得分:0)

此答案更多地与速度有关。

var precalculatedPrecisions = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10];

function round(num, _prec) {
    _precision = precalculatedPrecisions[_prec]
    return Math.round(num * _precision + 1e-14) / _precision ;
}

jsPerf

答案 73 :(得分:0)

使用Brian Ustas的解决方案:

function roundDecimal(value, precision) {
    var multiplier = Math.pow(10, precision);
    return Math.round(value * multiplier) / multiplier;
}

答案 74 :(得分:0)

number=(parseInt((number +0.005)*100))/100;     
如果你想要正常回合(2位小数),

加0.005;

8.123 +0.005=> 8.128*100=>812/100=>8.12   

8.126 +0.005=> 8.131*100=>813/100=>8.13   

答案 75 :(得分:0)

Node.js的

这在几秒钟内就 Node.js 为我做了诀窍:

npm install math

来源:http://mathjs.org/examples/basic_usage.js.html

答案 76 :(得分:0)

如果您不想四舍五入,请使用以下功能。

function ConvertToDecimal(num) {
  num = num.toString(); // If it's not already a String
  num = num.slice(0, (num.indexOf(".")) + 3); // With 3 exposing the hundredths place    
alert('M : ' + Number(num)); // If you need it back as a Number     
}

答案 77 :(得分:-1)

我尝试了自己的代码,试试这个

function AmountDispalyFormat(value) {
    value = value.toFixed(3);
    var amount = value.toString().split('.');
    var result = 0;
    if (amount.length > 1) {
        var secondValue = parseInt(amount[1].toString().slice(0, 2));
        if (amount[1].toString().length > 2) {
            if (parseInt(amount[1].toString().slice(2, 3)) > 4) {
                secondValue++;
                if (secondValue == 100) {
                    amount[0] = parseInt(amount[0]) + 1;
                    secondValue = 0;
                }
            }
        }

        if (secondValue.toString().length == 1) {
            secondValue = "0" + secondValue;
        }
        result = parseFloat(amount[0] + "." + secondValue);
    } else {
        result = parseFloat(amount);
    }
    return result;
}

答案 78 :(得分:-9)

我仍然认为没有人给他答案如何只在需要时进行四舍五入。我看到的最简单的方法是检查数字中是否还有小数,如下所示:

var num = 3.21;
if ( (num+"").indexOf('.') >= 0 ) { //at least assert to string first...
    // whatever code you decide to use to round
}