JavaScript:四捨五入された数値をN桁にフォーマットする


104

JavaScriptでは、数値を小数点以下N桁に丸める一般的な方法は次のようになります。

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

しかし、このアプローチは、ラウンドになり、最大 Nの小数点以下の桁の私はにはしたいしながら、常に Nの小数点以下の桁数に丸めます。たとえば、「2.0」は「2」に丸められます。

何か案は?


9
通常はtoFixed()developer.mozilla.org/En/Core_JavaScript_1.5_Reference/…)を使用できますが、IEにはバグがあります:stackoverflow.com/questions/661562/… ; あなたはあなた自身のバージョンを書かなければならないでしょう...
クリストフ

1
@hoju-承認された回答を変更する可能性があります-Davidの回答はIE8 +に対して正解ですが、承認された回答にはすべてのブラウザーでいくつかの深刻なバグがあります。
robocat

@robocat:本気ですか?
グッファ

回答:


25

これは丸い問題ではなく、表示の問題です。数値には、有効数字に関する情報は含まれていません。値2は2.0000000000000と同じです。丸められた値を文字列に変換すると、特定の桁数が表示されます。

次のように、数値の後にゼロを追加するだけです。

var s = number.toString();
if (s.indexOf('.') == -1) s += '.';
while (s.length < s.indexOf('.') + 4) s += '0';

(これは、クライアントの地域設定でピリオドを小数点として使用することを前提としていることに注意してください。コードが他の設定で機能するには、さらに作業が必要です。)


3
toFixedはバグが多いです。たとえば、10進数:1.02449999998の場合、dec.toFixed(4)=> 1.0244を実行します。代わりに1.0245でした。
Bat_Programmer '19 / 09/19

2
@deepeshkしかしtoFixed()、丸めた後、最後に小数を埋め込むためにを使用する場合の問題は何でしょうか?
pauloya

10
どのブラウザで@deepeshk?Chrome 17で試してみて、1.02449999998.toFixed(4)正しく戻ります1.0245
マットボール

3
@MarkTomlin:数値ではなく文字列があるようです。
Guffa 2013年

1
.toFixed()は、最新のブラウザー(Chrome、Firefox、IE11、IE8でテストしました)で見事に機能します。@Bat_Programmer-明確にしくださいバグがあると思わブラウザ。
robocat 2015年

243

ここで示した方法にはすべてもっと簡単な方法があると思いNumber.toFixed()ます。これは、JavaScriptですでに実装されているメソッドです。

単に書く:

var myNumber = 2;

myNumber.toFixed(2); //returns "2.00"
myNumber.toFixed(1); //returns "2.0"

等...


宝珠はどこに言及されていますか?他の回答を確認しましたが、toFixed関数にバグがあると報告している人は見つかりませんでした。おかげで
デビッド14

@David:たとえば、回答へのコメントで言及されています。
Guffa

13
注意:toFixed()文字列を返します。
ヨルダンアルセノ2015

2
@JordanArsenoこれは、parseInt(myNumber.toFixed(intVar));を使用して修正できます。整数値を返す、またはparseFloat(myNumber.toFixed(floatVar)); ユーザーが小数点以下の桁数を持っている場合は浮動小数点数を返します。
Stephen Romero、

50

私は方法を発見しました。これは修正されたクリストフのコードです:

function toFixed(value, precision) {
    var precision = precision || 0,
        power = Math.pow(10, precision),
        absValue = Math.abs(Math.round(value * power)),
        result = (value < 0 ? '-' : '') + String(Math.floor(absValue / power));

    if (precision > 0) {
        var fraction = String(absValue % power),
            padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
        result += '.' + padding + fraction;
    }
    return result;
}

「+ 1」を追加した理由について知りたくない場合は、配列コンストラクターを使用して文字を繰り返す方法の詳細をここで読んでください。


精度が2または3の708.3333333333333の値を渡すと、戻り値は708.00になります。私はこれを小数点第2位で必要とし、ChromeとIE 9では.toFixed(2)が私のニーズを満たしました。
アラン

これは一般的な方法ではありません。たとえば、toFixed(16.775、2)は16.77を返します。数値を文字列に変換してから変換するのが唯一の方法です。
ハイウェイ2014年

2
このメソッドにはバグがあります:toFixed(-0.1111、2)は0.11を返します。つまり、負の符号は失われます。
マット

最後にparseFloat(result)を追加したことを除いて、うまく動作します。編集に値する。
Artur Barseghyan 2015年

16

物事を行うためのより良い方法は常にあります。

var number = 51.93999999999761;

4桁の精度を取得したい:51.94

ただやる:

number.toPrecision(4);

結果は次のようになります:51.94


2
100を追加するとどうなるでしょうか。number.toPrecision(5)に変更する必要がありますか?
JohnnyBizzle

2
はい。31.939383.toPrecision(4)> "31.94" / 131.939383.toPrecision(4)> "131.9"
ReSpawN

6

PHPに似た丸め方法

以下のコードを使用して、独自のバージョンのMath.roundを、精度パラメーターを受け取る独自の名前空間に追加できます。上記の例の10進数の丸めとは異なり、これは文字列との間の変換を行わず、精度パラメーターはPHPおよびExcelと同じように機能し、正の1は小数点以下1桁に丸められ、-1は10桁に丸められます。

var myNamespace = {};
myNamespace.round = function(number, precision) {
    var factor = Math.pow(10, precision);
    var tempNumber = number * factor;
    var roundedTempNumber = Math.round(tempNumber);
    return roundedTempNumber / factor;
};

myNamespace.round(1234.5678, 1); // 1234.6
myNamespace.round(1234.5678, -1); // 1230

Math.round()のMozilla Developerリファレンスから


2

うまくいけば、コードは機能します(テストはあまり行いませんでした)。

function toFixed(value, precision) {
    var precision = precision || 0,
        neg = value < 0,
        power = Math.pow(10, precision),
        value = Math.round(value * power),
        integral = String((neg ? Math.ceil : Math.floor)(value / power)),
        fraction = String((neg ? -value : value) % power),
        padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');

    return precision ? integral + '.' +  padding + fraction : integral;
}

コードにバグがあります。toFixed(2.01、4)を試してみると「2.100」という結果が出ました。修正方法が見つかった場合は、この質問への回答として投稿します。
エリアスザマリア

@ mikez302:パディングの計算が1つずれていました。今は動作するはずですが、まだ壊れている場合は、遠慮なくもう一度バグを報告してください...
Christoph

非常に奇妙な。firefox 17でfirebugコンソールを開いてこの機能を実行すると、jsが無限ループに陥るようにブラウザー全体がフリーズします。出力をconsole.logしない場合でも。firebugをアクティブにしていない場合、バグは発生しません。
SublymeRick 2013年

1
更新、私はそれをクロムで実行しました:Uncaught RangeError:toFixed関数呼び出しに関して最大​​呼び出しスタックサイズを超えました。
SublymeRick 2013年

@SublymeRick:なぜこれが起こるのか私にはわかりません。暗闇の中で撮影:関数の名前を変更してみてください
Christoph

2

以下の機能が役立つと思います

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

使用法:roundOff(600.23458,2);戻ります600.23


2

これは、N桁に丸める場合に機能します(N桁に切り捨てる場合は、Math.round呼び出しを削除して、Math.trunc呼び出しを使用します)。

function roundN(value, digits) {
   var tenToN = 10 ** digits;
   return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
}

私がデータ操作E-Slateコンポーネントを作成していたとき、過去にJavaでそのようなロジックに頼らなければなりませんでした。これは、0に0.1を何度も加算すると、予期せぬ長い10進数部分が発生することがわかったためです(これは、浮動小数点演算によるものです)。

常に小数点以下2桁を表示する形式番号でのユーザーコメントは、この手法のスケーリングと呼ばれます。

期待どおりに丸められない場合があるとの指摘があり、代わりにhttp://www.jacklmoore.com/notes/rounding-in-javascript/をお勧めします。

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

ところで、POSITSは将来のハードウェアアーキテクチャに有望です。nextplatform.com/ 2019/07/08
George Birbilis

-2

丸めを気にしない場合は、toFixed(x)を追加し、必要に応じて末尾の0とドットを削除します。これは高速なソリューションではありません。

function format(value, decimals) {
    if (value) {
        value = value.toFixed(decimals);            
    } else {
        value = "0";
    }
    if (value.indexOf(".") < 0) { value += "."; }
    var dotIdx = value.indexOf(".");
    while (value.length - dotIdx <= decimals) { value += "0"; } // add 0's

    return value;
}

期待していたのですformat(1.2, 5)1.2、試してみました1.20000
エリアスザマリア2014年

申し訳ありませんが、@ EliasZamariaは最初は理解できませんでした。投稿を編集しました。値が未定義の場合は「0.0000」を返すことに注意してください。
Juan Carrey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.