web-dev-qa-db-ja.com

JavaScriptでフロートをフォーマットする方法?

JavaScriptで、floatから文字列に変換するときに、小数点以下2桁にするにはどうすればよいですか。たとえば、0.3445434ではなく0.34です。

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

細部 コードが一目瞭然ではない場合。

編集:...または TimBüthe によって提案されているようにtoFixedを使用してください。忘れてしまった、リマインダーをありがとう(そして投票):)

212
kkyy

四捨五入する機能があります。例えば:

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

5.04を印刷します。

編集: Fiddle

780
Tim Büthe

toFixed()を使うときは注意してください。

まず、数値の丸めは数値の2進表現を使用して行われるため、予期しない動作が生じる可能性があります。例えば

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

'0.6'の代わりに。

次に、toFixed()にIEバグがあります。 IE(少なくともバージョン7までは、IE 8をチェックしていませんでした)では、次のことが当てはまります。

(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);
}
178
Christoph

もう1つ注意が必要な問題は、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"
32
qbolec
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make Nice rounding
10
Ilya Birman

乗数を使用して浮遊するこれらすべての解決策には問題があります。 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;
}
5
ArteQ

ここで重要なことは、最初に正しく切り上げてから、それを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
3
Steven
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;
}
1
ofir_aghai

乗算または除算のいずれかを使用してx.xx5を実際の値として使用すると、価格の一貫性のない丸めを回避する方法はありません。クライアントサイドで正しい価格を計算する必要がある場合は、すべての金額をセント単位で維持する必要があります。これはJavaScriptの数値の内部表現の性質によるものです。 Excelも同じ問題を抱えているので、ほとんどの人はこの現象による小さなエラーに気付かないでしょう。ただし、計算値を大量に加算するたびに誤差が累積する可能性があります。これには、計算順序や最終結果の誤差を最小限に抑えるためのその他の方法を含む理論全体があります。 10進数値の問題を強調するために、JavaScriptでは0.1 + 0.2が0.3と正確に等しいわけではないのに対し、1 + 2は3と等しくないことに注意してください。

0
Dony

ラウンドなしの文字列が必要な場合は、この正規表現を使用できます(おそらく最も効率的な方法ではありませんが、本当に簡単です)

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

たぶんあなたも小数点の区切り記号が必要ですか?これが私が作ったばかりの関数です。

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

フロートをフォーマットするためにこのコードを使います。これは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>');
0
Mark
/** 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"
0
reuns