如何在javascript中格式化浮点数?

时间:2009-03-19 09:38:01

标签: javascript floating-point

在JavaScript中,当从float转换为字符串时,如何在小数点后只获得2位数?例如,0.34而不是0.3445434。

15 个答案:

答案 0 :(得分:780)

有圆形数字的功能。例如:

var x = 5.0364342423;
print(x.toFixed(2));

将打印5.04。

修改 Fiddle

答案 1 :(得分:213)

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

The specifics,如果代码不能自我解释。

编辑:...或仅使用toFixed建议的Tim Büthe。忘了那个,谢谢(和upvote)提醒:)

答案 2 :(得分:178)

使用toFixed()时要小心:

首先,使用数字的二进制表示来完成数字舍入,这可能会导致意外行为。例如

(0.595).toFixed(2) === '0.59'

而不是'0.6'

其次,toFixed()存在IE漏洞。在IE中(至少达到版本7,没有检查IE8),以下情况属实:

(0.9).toFixed(0) === '0'

遵循kkyy的建议或使用自定义toFixed()功能可能是个好主意,例如

function toFixed(value, precision) {
    var power = Math.pow(10, precision || 0);
    return String(Math.round(value * power) / power);
}

答案 3 :(得分:32)

需要注意的另一个问题是,toFixed()会在数字末尾产生不必要的零。 例如:

var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"

我们的想法是使用RegExp

清理输出
function humanize(x){
  return x.toFixed(6).replace(/\.?0*$/,'');
}

RegExp匹配尾随零(以及可选的小数点),以确保它看起来也适用于整数。

humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"

答案 4 :(得分:10)

var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding

答案 5 :(得分:5)

所有使用乘数浮动的解决方案都存在问题。不幸的是,kkyy和Christoph的解决方案都是错误的。

请测试您的代码号码 551.175 ,小数点后2位 - 它会四舍五入 551.17 ,而它应该 551.18 !但如果你测试前。 451.175就可以了 - 451.18。因此,乍看之下很难发现这个错误。

问题在于倍增:尝试551.175 * 100 = 55117.49999999999(ups!)

所以我的想法是在使用Math.round();

之前用toFixed()对待它
function roundFix(number, precision)
{
    var multi = Math.pow(10, precision);
    return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}

答案 6 :(得分:3)

我想这里的关键是首先正确地向上舍入,然后你可以将它转换为String。

function roundOf(n, p) {
    const n1 = n * Math.pow(10, p + 1);
    const n2 = Math.floor(n1 / 10);
    if (n1 >= (n2 * 10 + 5)) {
        return (n2 + 1) / Math.pow(10, p);
    }
    return n2 / Math.pow(10, p);
}

// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34

现在您可以使用toFixed(p)安全地格式化此值。 因此,根据您的具体情况:

roundOf(0.3445434, 2).toFixed(2); // 0.34

答案 7 :(得分:1)

function trimNumber(num, len) {
  const modulu_one = 1;
  const start_numbers_float=2;
  var int_part = Math.trunc(num);
  var float_part = String(num % modulu_one);
      float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
  return int_part+'.'+float_part;
}

答案 8 :(得分:0)

也许你还想要小数点分隔符?这是我刚才做的一个功能:

function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
    if (num < 0)
    {
        num = -num;
        sinal = -1;
    } else
        sinal = 1;
    var resposta = "";
    var part = "";
    if (num != Math.floor(num)) // decimal values present
    {
        part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
        while (part.length < casasDec)
            part = '0'+part;
        if (casasDec > 0)
        {
            resposta = sepDecimal+part;
            num = Math.floor(num);
        } else
            num = Math.round(num);
    } // end of decimal part
    while (num > 0) // integer part
    {
        part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
        num = Math.floor(num/1000);
        if (num > 0)
            while (part.length < 3) // 123.023.123  if sepMilhar = '.'
                part = '0'+part; // 023
        resposta = part+resposta;
        if (num > 0)
            resposta = sepMilhar+resposta;
    }
    if (sinal < 0)
        resposta = '-'+resposta;
    return resposta;
}

答案 9 :(得分:0)

使用乘法或除法,无法避免x.xx5作为实际值的价格出现不一致的舍入。如果您需要计算客户端的正确价格,您应该将所有金额保持在美分。这是由于JavaScript中数值的内部表示的性质。请注意,Excel遇到了同样的问题,因此大多数人都不会注意到这个现象引起的小错误。但是,每当您将大量计算值相加时,错误可能会累积,有一个完整的理论涉及计算顺序和其他方法以最小化最终结果中的错误。为了强调十进制值的问题,请注意在JavaScript中0.1 + 0.2并不完全等于0.3,而1 + 2等于3.

答案 10 :(得分:0)

/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) { 
    if (!nbDec) nbDec = 100;
    var a = Math.abs(x);
    var e = Math.floor(a);
    var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
    var signStr = (x<0) ? "-" : " ";
    var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
    var eStr = e.toString();
    return signStr+eStr+"."+decStr;
}

prettyFloat(0);      //  "0.00"
prettyFloat(-1);     // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5);    //  "0.50"

答案 11 :(得分:0)

我使用此代码格式化浮点数。它基于toPrecision(),但它删除了不必要的零。我欢迎有关如何简化正则表达式的建议。

function round(x, n) {
    var exp = Math.pow(10, n);
    return Math.floor(x*exp + 0.5)/exp;
}

用法示例:

function test(x, n, d) {
    var rounded = rnd(x, d);
    var result = rounded.toPrecision(n);
    result = result.replace(/\.?0*$/, '');
    result = result.replace(/\.?0*e/, 'e');
    result = result.replace('e+', 'e');
    return result;  
}

document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');

答案 12 :(得分:0)

如果您想要不带圆角的字符串,则可以使用此RegEx(也许不是最有效的方法,但是确实很简单)

(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'

答案 13 :(得分:0)

countDecimals = value => {
    if (Math.floor(value) === value) return 0;
    let stringValue = value.toString().split(".")[1];
    if (stringValue) {
      return value.toString().split(".")[1].length
        ? value.toString().split(".")[1].length
        : 0;
    } else {
      return 0;
    }
  };
  
formatNumber=(ans)=>{
    let decimalPlaces = this.countDecimals(ans);
    ans = 1 * ans;
    if (decimalPlaces !== 0) {
      let onePlusAns = ans + 1;
      let decimalOnePlus = this.countDecimals(onePlusAns);
      if (decimalOnePlus < decimalPlaces) {
        ans = ans.toFixed(decimalPlaces - 1).replace(/\.?0*$/, "");
      } else {
        let tenMulAns = ans * 10;
        let decimalTenMul = this.countDecimals(tenMulAns);
        if (decimalTenMul + 1 < decimalPlaces) {
          ans = ans.toFixed(decimalPlaces - 1).replace(/\.?0*$/, "");
        }
      }
    }
}

我只需在值上加1并计算原始值和相加后的值中出现的小数位数。如果我在减去原始十进制数字后再找到十进制数字,则只需使用(原始十进制数-1)调用toFixed()。我还通过将原始值乘以10进行检查,并遵循相同的逻辑,以防加一不会减少多余的小数位。 一个简单的解决方法,用于处理JS中的浮点数舍入。在我尝试过的大多数情况下都可以。

答案 14 :(得分:-2)

    You can try this if you want don't want to use rounding
 function myFunction() {
            var str = 12.234556; 
            str = str.toString().split('.');
            var res = str[1].slice(0, 2);
            document.getElementById("demo").innerHTML = str[0]+'.'+res;
        }
output:12.23

str.toString().split('.')会将您的浮点数转换为字符串,然后将其拆分为“。”

结果变量将是一个带有两个字符串类型元素的数组,第一个元素将是12,第二个元素将是234556

str[1].slice(0, 2)会将你的第二个(234556)字符串分成前两个字符,即23

然后通过str[0]+'.'+res

连接第一个和结果字符串

希望这会有所帮助