在JavaScript中使用正好两位小数格式化数字

我有这行代码将我的数字四舍五入到小数点后两位。 但是我得到这样的数字:10.8、2.4等。这些不是我对小数点后两位的想法,因此我如何改善以下内容?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

我想要数字10.80、2.40等。使用jQuery对我来说很好。


#1楼

toFixed(n)提供小数点后的n个长度; toPrecision(x)提供x的总长度。

在下面使用此方法

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

并且,如果您希望该号码固定使用

result = num.toFixed(2);

#2楼

@heridev和我在jQuery中创建了一个小函数。

您可以尝试下一个:

的HTML


jQuery的

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

网上演示:

http://jsfiddle.net/c4Wqn/


#3楼

我通常将其添加到我的个人库中,在提出一些建议并也使用@TIMINeutron解决方案之后,使其适用于十进制长度,这是最合适的:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

将适用于所报告的异常。


#4楼

我没有找到解决此问题的准确方法,因此我创建了自己的解决方案:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

例子:

 function inprecise_round(value, decPlaces) { return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces); } function precise_round(value, decPlaces) { var val = value * Math.pow(10, decPlaces); var fraction = (Math.round((val - parseInt(val)) * 10) / 10); //this line is for consistency with .NET Decimal.Round behavior // -342.055 => -342.06 if (fraction == -0.5) fraction = -0.6; val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces); return val; } // This may produce different results depending on the browser environment console.log("342.055.toFixed(2) :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10 console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05 console.log("precise_round(342.055, 2) :", precise_round(342.055, 2)); // 342.06 console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2)); // -342.06 console.log("inprecise_round(0.565, 2) :", inprecise_round(0.565, 2)); // 0.56 console.log("precise_round(0.565, 2) :", precise_round(0.565, 2)); // 0.57 


#5楼

我不知道为什么不能在以前的答案中添加评论(也许我是无可救药的盲人,不知道),但是我想出了一个使用@Miguel答案的解决方案:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

及其两个注释(来自@bighostkim和@Imre):

  • precise_round(1.275,2)不返回1.28的问题
  • precise_round(6,2)不返回6.00的问题(如他所愿)。

我的最终解决方案如下:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

如您所见,我不得不添加一点“更正”(不是这样,但是由于Math.round有损-您可以在jsfiddle.net上进行检查-这是我知道如何“修复”的唯一方法”。 它会将0.001加到已填充的数字上,因此它会在十进制值的右边加一个1 3 0 s。 因此使用起来应该安全。

之后,我添加了.toFixed(decimal)以始终以正确的格式(带有正确的小数位数)输出数字。

就是这样。 很好地使用它;)

编辑:为负数的“更正”添加了功能。


#6楼

要使用定点表示法格式化数字,可以简单地使用toFixed方法:

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

请注意, toFixed()返回一个字符串。

重要说明 :请注意,toFixed实际上不会舍入,在90%的时间中,它将返回舍入后的值,但是在许多情况下,它实际上并不起作用。 在控制台中尝试以下操作:

2.005.toFixed(2)

您会得到错误的答案

没有自然的方法来获取javascript中的小数位舍入,您将需要自己的polyfill或使用库。 您可以通过以下网址查看mozilla的polyfill :https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round


#7楼

浮点值的问题在于它们试图用固定数量的位表示无限数量的(连续)值。 因此,自然而然地,一定会有一些损失,而您会被一些价值所困扰。

当计算机将1.275存储为浮点值时,它实际上将不记得它是1.275还是1.27499999999999993,甚至是1.27500000000000002。 这些值四舍五入到小数点后两位时应给出不同的结果,但它们不会,因为对于计算机,它们在存储为浮点值后看起来完全一样 ,并且无法恢复丢失的数据。 任何进一步的计算只会累积这种不精确性。

因此,如果精度很重要,则必须从一开始就避免浮点值。 最简单的选择是

  • 使用专门的图书馆
  • 使用字符串来存储和传递值(伴随字符串操作)
  • 使用整数(例如,您可能传递的是实际价值的百分之一,例如,以美分而不是美元为单位)

例如,当使用整数存储百分之一的数字时,用于查找实际值的函数非常简单:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

使用字符串,您需要四舍五入,但是仍然可以管理:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

请注意,此函数四舍五入为最接近零的关系 ,而IEEE 754建议将四舍五入为最接近的关系,作为浮点运算的默认行为。 这些修改留给读者练习:)


#8楼

这是一个简单的

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i

使用像alert(roundFloat(1.79209243929,4));

杰斯菲德尔


#9楼

一种获得100%确定带有2个小数的数字的方法:

(Math.round(num*100)/100).toFixed(2)

如果这导致舍入错误,则可以使用James在其评论中解释的以下内容:

(Math.round((num * 1000)/10)/100).toFixed(2)

#10楼

这是一个古老的话题,但仍是Google排名最高的结果,提供的解决方案也存在相同的浮点小数问题。 这是我使用的(非常通用的)函数, 这要感谢MDN :

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(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

这种通用性还提供了一些很酷的东西:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

现在,要回答OP的问题,必须输入:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

或者,对于更简洁,不太通用的功能:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

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

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

您可以通过以下方式调用它:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

各种示例和测试(感谢@ tj-crowder !):

 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)); } function naive(value, exp) { if (!exp) { return Math.round(value); } var pow = Math.pow(10, exp); return Math.round(value * pow) / pow; } function test(val, places) { subtest(val, places); val = typeof val === "string" ? "-" + val : -val; subtest(val, places); } function subtest(val, places) { var placesOrZero = places || 0; var naiveResult = naive(val, places); var roundResult = round(val, places); if (placesOrZero >= 0) { naiveResult = naiveResult.toFixed(placesOrZero); roundResult = roundResult.toFixed(placesOrZero); } else { naiveResult = naiveResult.toString(); roundResult = roundResult.toString(); } $("") .append($("").text(JSON.stringify(val))) .append($("").text(placesOrZero)) .append($("").text(naiveResult)) .append($("").text(roundResult)) .appendTo("#results"); } test(0.565, 2); test(0.575, 2); test(0.585, 2); test(1.275, 2); test(1.27499, 2); test(1234.5678, -2); test(1.2345678e+2, 2); test("123.45"); test(10.8034, 2); test(10.8, 2); test(1.005, 2); test(1.0005, 2); 
 table { border-collapse: collapse; } table, td, th { border: 1px solid #ddd; } td, th { padding: 4px; } th { font-weight: normal; font-family: sans-serif; } td { font-family: monospace; } 
 
Input Places Naive Thorough


#11楼

以下内容放在全局范围内:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

然后尝试

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

更新资料

请注意, toFixed()仅适用于0-200-20之间的小数位数,即a.getDecimals(25)可能会产生JavaScript错误,因此为了适应您可以添加一些其他检查,即

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}

#12楼

四舍五入您的十进制值,然后使用toFixed(x)作为您的期望数字。

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

呼叫

parseDecimalRoundAndFixed(10.800243929,4)=> 10.80 parseDecimalRoundAndFixed(10.807243929,2)=> 10.81


#13楼

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

这对我有用:在JavaScript中舍入小数


#14楼

(Math.round((10.2)*100)/100).toFixed(2)

那应该产生: 10.20

(Math.round((.05)*100)/100).toFixed(2)

那应该产生: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

那应该产生: 4.04

等等


#15楼

我解决了修饰符的问题。 仅支持2个小数。

 $(function(){ //input number only. convertNumberFloatZero(22); // output : 22.00 convertNumberFloatZero(22.5); // output : 22.50 convertNumberFloatZero(22.55); // output : 22.55 convertNumberFloatZero(22.556); // output : 22.56 convertNumberFloatZero(22.555); // output : 22.55 convertNumberFloatZero(22.5541); // output : 22.54 convertNumberFloatZero(22222.5541); // output : 22,222.54 function convertNumberFloatZero(number){ if(!$.isNumeric(number)){ return 'NaN'; } var numberFloat = number.toFixed(3); var splitNumber = numberFloat.split("."); var cNumberFloat = number.toFixed(2); var cNsplitNumber = cNumberFloat.split("."); var lastChar = splitNumber[1].substr(splitNumber[1].length - 1); if(lastChar > 0 && lastChar < 5){ cNsplitNumber[1]--; } return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]); }; }); 
  


#16楼

Number(((Math.random() * 100) + 1).toFixed(2))

这将返回从1到100的随机数,四舍五入到小数点后2位。


#17楼

 /*Due to all told stuff. You may do 2 things for different purposes: When showing/printing stuff use this in your alert/innerHtml= contents: YourRebelNumber.toFixed(2)*/ var aNumber=9242.16; var YourRebelNumber=aNumber-9000; alert(YourRebelNumber); alert(YourRebelNumber.toFixed(2)); /*and when comparing use: Number(YourRebelNumber.toFixed(2))*/ if(YourRebelNumber==242.16)alert("Not Rounded"); if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded"); /*Number will behave as you want in that moment. After that, it'll return to its defiance. */ 


#18楼

这非常简单,并且与其他任何方法一样有效:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

由于toFixed()只能在数字上调用,并且不幸地返回一个字符串,因此这将为您双向进行所有解析。 您可以传递一个字符串或数字,并且每次都返回一个数字! 调用parseNumber(1.49)将给您1,而parseNumber(1.49,2)将给您1.50。 就像他们最好的一样!


#19楼

您还可以使用.toPrecision()方法和一些自定义代码,并且始终将其舍入为第n个十进制数字,而不管int部分的长度如何。

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

您还可以使其成为更好使用的插件。


#20楼

通过引用使用此响应: https : //stackoverflow.com/a/21029698/454827

我建立了一个获取动态小数位数的函数:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

这里的工作示例: https : //jsfiddle.net/wpxLduLc/


#21楼

 parse = function (data) { data = Math.round(data*Math.pow(10,2))/Math.pow(10,2); if (data != null) { var lastone = data.toString().split('').pop(); if (lastone != '.') { data = parseFloat(data); } } return data; }; $('#result').html(parse(200)); // output 200 $('#result1').html(parse(200.1)); // output 200.1 $('#result2').html(parse(200.10)); // output 200.1 $('#result3').html(parse(200.109)); // output 200.11 
  


#22楼

100%工作!!! 试试吧

         


#23楼

四舍五入

function round_down(value, decPlaces) {
    return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

围捕

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

舍入最近

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

合并https://stackoverflow.com/a/7641824/1889449和https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm谢谢。


#24楼

在这些示例中,尝试对数字1.005进行四舍五入时仍然会出现错误,解决方案是使用Math.js之类的库或使用以下函数:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}

#25楼

 /** * 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 +ve 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 // testing some -ve 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 


#26楼

这是我的一线解决方案: Number((yourNumericValueHere).toFixed(2));

这是发生了什么:

1)首先,将.toFixed(2)应用于要四舍五入到小数点后的数字。 请注意,这会将值转换为数字的字符串。 因此,如果您使用的是Typescript,它将引发如下错误:

“类型'字符串'不可分配给类型'数字'”

2)要获取数值或将字符串转换为数值,只需将Number()函数应用于该所谓的“字符串”值即可。

为了澄清起见,请看下面的示例:

示例:我的金额在小数点后最多5位,我想将其缩短到小数点后2位。 我这样做是这样的:

 var price = 0.26453; var priceRounded = Number((price).toFixed(2)); console.log('Original Price: ' + price); console.log('Price Rounded: ' + priceRounded); 


#27楼

几个月前,我从这篇文章中得到了一些想法,但是这里没有任何答案,也没有其他帖子/博客的答案可以解决所有情况(例如,测试人员发现的负数和一些“幸运数字”)。 最后,我们的测试人员在下面的此方法中未发现任何问题。 粘贴我的代码片段:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

我也有代码注释(对不起,我已经忘记了所有详细信息)...我在这里发布我的答案以供将来参考:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).

#28楼

就这么简单。

var rounded_value=Math.round(value * 100) / 100;

#29楼

我找到了一种非常简单的方法为我解决了这个问题,可以使用或改编:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

你可能感兴趣的:(javascript,rounding,decimal-point)