web-dev-qa-db-ja.com

小数点以下2桁以下に丸めます(必要な場合のみ)

小数点以下第2位までを四捨五入したいのですが、 必要な場合だけ

入力:

10
1.7777777
9.1

出力:

10
1.78
9.1

JavaScriptでこれを行うにはどうすればいいですか。

2209
stinkycheeseman

Math.round(num * 100) / 100を使う

2796
Brian Ustas

値がテキスト型の場合

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が実際には裏側にあるfloat 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

Solution 2はフロントエンドの計算を避け、バックエンドサーバーから丸められた値を引き出すことです。

2649
A Kunin

あなたが使用することができます

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

これを _ mdn _ で見つけました。彼らのやり方は 言及されていた1.005の問題を回避します

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

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

.toFixed(NumberOfDecimalPlaces)を使うことができます。

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

正確な丸め方法出典: 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
62
user

.toFixed().toPrecision()を考えます。

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

60
AceCorban

ここで見つかった答えはどれも正しいものではありません 。 @stinkycheesemanは に切り上げを求めました 、あなたはすべて数字を丸めました。

切り上げるには、これを使います。

Math.ceil(num * 100)/100;
56
machineaddict

あなたが使用する必要があります:

Math.round( num * 100 + Number.EPSILON ) / 100

Number.EPSILON に気づいている人はいないようです。

また、これがJavaScriptの奇妙さではないということも注目に値します。

これは単に浮動小数点数がコンピュータで機能する方法です。 99%のプログラミング言語のように、JavaScriptは自家製浮動小数点数を持っていません。それはCPU/FPUに依存しています。コンピュータはバイナリを使用し、バイナリでは0.1のような数値はありませんが、それを表す単なるバイナリ近似です。どうして? 1/3と同じ理由で10進数で書くことはできません。その値は0.33333333 ...で、無限大は3です。

これが Number.EPSILON です。その数は、1と倍精度浮動小数点数に存在するnext数の差です。 それだけです:1と1 + Number.EPSILONの間に数字はありません。

編集:

コメントで尋ねられたように、一つのことを明確にしましょう:Number.EPSILONを追加することは、浮動小数点誤差デルタを飲み込むことができるので、roundへの値が算術演算の結果であるときだけ関係があります。

値が直接の情報源(例:文字列、ユーザー入力、センサーなど)から来る場合は役に立ちません。

48
cronvel

簡単な方法は次のとおりです。

Math.round(value * 100) / 100

あなたは先に行き、あなたのためにそれをするために別の機能を作ることを望むかもしれません:

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

それからあなたは単に値を渡します。

2番目のパラメータを追加することで、任意の小数点以下の桁数に丸めるように拡張することができます。

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

    return (Math.round(value * multiplier) / multiplier);
}
44
JayDM
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

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

私にとっては Math.round() は正解していませんでした。 toFixed(2) を見つけました。以下は両方の例です。

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

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

2017年
ネイティブコード.toFixed()を使う

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

厳密で、必要に応じて数字を追加する必要がある場合はreplaceを使用できます。

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

この関数を使うNumber(x).toFixed(2);

31
Harish.bazee

これを試してください 軽量 解決策:

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

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

それにはいくつかの方法があります。私のような人々のために、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

28
stanleyxu2005

MarkGとLavamantisは、受け入れられているものよりもはるかに優れたソリューションを提供しました。それは彼らがより多くの投票を得ないのは残念です!

これは、浮動小数点小数の問題を解決するために使用する関数です。 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
22
astorije

Lodashライブラリを使用している場合は、次のようにlodashのラウンド方式を使用できます。

_.round(number, precision)

例えば:

_.round(1.7777777, 2) = 1.78
20
Madura Pradeep

これはあなたを助けるかもしれません:

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

詳しくは、このリンクをご覧ください。

Math.round(num)とnum.toFixed(0)とブラウザの不一致

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

ここでtoFixed(2) 2はこの数を四捨五入したい桁数です。

16
Ritesh Dhuri

このようなものを使用してください "parseFloat(parseFloat(value).toFixed(2))"

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

最も簡単な方法:

+num.toFixed(2)

それを文字列に変換してからinteger/floatに戻します。

12
Edmund

それはあなたのために働くかもしれません、

Math.round(num * 100)/100;

toFixedとroundの違いを知るために。Math.round(num)vs num.toFixed(0)とブラウザの不一致をご覧ください。

12
Shreedhar

これがプロトタイプメソッドです。

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

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

一般に、丸めはスケーリングによって行われます。round(num / p) * p

指数表記を使用すると、+ ve数の四捨五入が正しく処理されます。ただし、この方法ではEdgeケースを正しく四捨五入できません。

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

これも、算術丸めを正しく行うために書いた1つの関数です。あなたはそれを自分でテストすることができます。

/**
 * 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
11
Amr Ali

ES6以降、 によってこれを行うための(適切な)(静的をオーバーライドして回避策を作成することなく)方法があります - toPrecision を使用して

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));
11

多くの0を扱わないようにするには、次のようにします。

Math.round(num * 1e2) / 1e2
10
Daniel De León

あなたがすでに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
9
Scott Stafford

より簡単な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
8
Adam A.

そのような丸めを実現する1つの方法 必要な場合に限り Number.prototype.toLocaleString()を使用することです

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

これはあなたが期待する出力を正確に提供するでしょう、しかしストリングとして。期待するデータ型ではない場合でも、これらを数値に戻すことができます。

8
Javarome

あなたが切り上げたいのであれば簡単な解決策は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を与える

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
7

もう1つアプローチを追加します。

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"

.toFixed(2)は正確に小数点以下2桁の文字列を返します。 parseFloat()を実行することはそれらの末尾のゼロを排除するでしょう。

7
Marcos Lima

同じ質問に対する 選択された回答 および 支持されたコメント に基づく:

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

これは、これら両方の例で機能します。

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

Math.round((1.0049 + 0.00001) * 100) / 100
7
Fellow Stranger

parseFloat( "1.555")。toFixed(2); // 1.56ではなく1.55を返します。

コンピュータに1.555の正確な表現が存在しないため、1.55が絶対的な正しい結果です。 1.555を読む場合、それは最も近い可能な値= 1.55499999999999994(64ビットfloat)に丸められます。そしてこの数をtoFixed(2)で丸めると1.55になります。

入力が1.55499999999999の場合、ここで提供されている他のすべての機能はフォルト結果を出します。

解決策:数字を切り上げるためにスキャンする前に数字の「5」を追加します(より正確には0から切り捨て)。これは、数値が実際には浮動小数点数(小数点がある)の場合にのみ実行してください。

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

多くの答えがあることを私は知っていますが、それらのほとんどはある特定の場合には副作用があります。

副作用のない最も簡単で最短の解決策は次のとおりです。

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
6
Nicolo

これは私にとってはうまくいった(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
5
Ross

別の方法はライブラリを使用することです。なぜlodash

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

私は簡単なtipCalculatorを構築していましたが、ここでは問題を複雑にしすぎると思われる多くの回答がありました。それで、私はこの問題を要約することが本当にこの質問に答えるための最良の方法であるとわかりました

丸めた10進数を作成したい場合は、まず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
4
Denis S Dujota

これが最短かつ完全な答えです:

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

これは、1.01を返す、ケース1.005の例にも気を配っています。

4
momomo

JQuery .numberプラグインを使用してみてください

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

小数点以下の桁数を丸めるには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" />
3
loretoparisi

これは私が "切り上げ"をするために思いついた関数です。 JavaScriptの不正確な乗算を補正するために二重のMath.roundを使用したので、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);
}
3
Andrei

私は自分自身のために以下の関数のセットを書きました。たぶんそれはあなたを助けるでしょう。

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
3
vsvasya

また、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/ /

3

真の正確な小数点以下の四捨五入精度を達成するために考えられるすべての方法のさまざまな反復を実行した後、最も正確で効率的な解決策がNumber.EPSILONを使用することであることは明らかです。これは、浮動小数点演算の精度の問題に対する真の数学的解法を提供します。それはここに示すように簡単にpolyfilledすることができます: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON 最後の残りのすべてをサポートするためにIE users(その場合もやはりそれをやめるべきです)。

ここで提供されているソリューションからの適応: https://stackoverflow.com/a/48850944/6910392

ライブラリ全体を追加することなく、オプションの精度変数を使用して、正確な小数点以下の四捨五入、床張り、および天井付けを提供する単純なソリューションドロップ。

var DecimalPrecision = (function(){
        if (Number.EPSILON === undefined) {
            Number.EPSILON = Math.pow(2, -52);
        }
        this.round = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.round((n + r) * o) / o;
        }
        this.ceil = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.ceil((n + r) * o) / o;
        }
        this.floor = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.floor((n + r) * o) / o;
        }
        return this;
    })();
    console.log(DecimalPrecision.round(1.005));
    console.log(DecimalPrecision.ceil(1.005));
    console.log(DecimalPrecision.floor(1.005));
    console.log(DecimalPrecision.round(1.0049999));
    console.log(DecimalPrecision.ceil(1.0049999));
    console.log(DecimalPrecision.floor(1.0049999));
    console.log(DecimalPrecision.round(2.175495134384,7));
    console.log(DecimalPrecision.round(2.1753543549,8));
    console.log(DecimalPrecision.round(2.1755465135353,4));
2
KFish

常に特定の10進数に切り上げたい場合、これは私にとってはかなりうまくいきました。ここで重要なことは、Math.ceil関数で常に切り上げることです。

必要に応じて、条件付きで天井または床を選択できます。

     /**
     * Possibility to lose precision at large numbers
     * @param number
     * @returns Number number
     */
    var roundUpToNearestHundredth = function(number) {

        // Ensure that we use high precision Number
        number = Number(number);

        // Save the original number so when we extract the Hundredth decimal place we don't bit switch or lose precision
        var numberSave = Number(number.toFixed(0));

        // Remove the "integer" values off the top of the number
        number = number - numberSave;

        // Get the Hundredth decimal places
        number *= 100;

        // Ceil the decimals.  Therefore .15000001 will equal .151, etc.
        number = Math.ceil(number);

        // Put the decimals back into their correct spot
        number /= 100;

        // Add the "integer" back onto the number
        return number + numberSave;

    };

console.log(roundUpToNearestHundredth(6132423.1200000000001))
2

これのわずかな違いは、通貨の金額を通貨全体または通貨の小数部分を含む金額としてフォーマットする必要がある場合です。

例えば:

1は$ 1を出力します

1.1は$ 1.10を出力するはずです

1.01は$ 1.01を出力するはずです

金額が数値であると仮定します:

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

Amountが数値でない場合は、parseFloat(amount)を使用して数値に変換します。

2
Ibraheem

既存の答えから、私は、うまくいくように思われる別の解決策を見つけました。

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

あなたがいくつかの強気で送るならば、それは考慮に入れません..しかし「apa」のように。あるいは、おそらく私が正しい方法であると思うエラーを投げるでしょう、(呼び出し関数によって)修正されるべきであるエラーを隠すのは決して良いことではありません。

2
OZZIE

前述の答えに基づいて、私は自分のアプローチを共有したいと思いました。

与えられた数値を、与えられた小数点以下の桁数に丸める関数を作りましょう。

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

そして数のプロトタイプのための新しい "round"メソッドを紹介します。

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

そしてあなたはそれをテストすることができます:

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);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="results"></div>
1
Deele

後のソートやその他の数学演算のためにtypeを整数として保持します。

Math.round(1.7777777 * 100)/100

1.77

または文字列に変換する:

(1.7777777).toFixed(2)

"1.77"

1
profimedica

これが、この問題に対する私の解決策です。

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

問題は、小数点以下2桁を丸めることです。

この複雑な修正プロトタイプチェーンなどを作らないようにしましょう。

ここに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));
1
Salman

レコードだけでは、四捨五入したい数と桁数が十分に大きい場合、スケーリング方法は理論的にはInfinityを返すことができます。 JavaScriptでは、最大数は1.7976931348623157e + 308なので問題にならないはずですが、本当に大きな数や小数点以下の桁数が多い場合は、代わりにこの関数を試すことができます。

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

この一見単純なタスクに対する大きな課題は、入力が最初に丸め誤差を最小限に抑えたとしても、心理的に期待される結果が得られるようにしたいということです(計算内で発生する誤差については言及しません)。実際の結果が正確に1.005であることがわかっていれば、たとえ1.005が途中で丸め誤差の負荷がある大規模計算の結果であっても、2桁に丸めると1.01になると予想されます。

floor()の代わりにround()を扱うとき、問題はさらに明白になります。例えば、33.3のドットの後ろ2桁を切り捨てると、確かにnotの結果は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を知りません。あなたがまだそれをサポートしなければならないという不幸な立場にいるなら、あなたはシムを使うか、あるいは単にその特定のブラウザファミリーのために定数を自分で定義することができます。

1
malamut

ノード環境では、 roundTo モジュールを使います。

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

// 123.46
1
Simon Prickett

すべてのブラウザと精度についての一般的な回答

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);
1
RBZ

_ mdn _ で見つかった precisionRound について提案された例(1.01ではなく1を返すそのイベント)から始めて、管理するカスタム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);
}
1
Marco Barbero

私はこれが私のすべてのユースケースに有効であることがわかりました。

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

これはES6です。 ES5相当コーディングは非常に簡単なので、追加するつもりはありません。

0
Rob Evans

Node.js

これは、 Node.js をほんの数秒で私のためにトリックしました:

npm install math

出典: http://mathjs.org/examples/basic_usage.js.html

0
nottinhill

四捨五入したくない場合は、以下の機能を使用してください。

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     
}
0
Nimesh

丸めの問題は指数表記で表される数を使用することによって回避することができます。

public static roundFinancial(amount: number, decimals: number) {
    return Number(Math.round(Number(`${amount}e${decimals}`)) + `e-${decimals}`);
}
0
Dmytro Medvid
number=(parseInt((number +0.005)*100))/100;     

通常のラウンドにしたい場合は0.005を加えてください(小数点以下2桁)

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

8.126 +0.005=> 8.131*100=>813/100=>8.13   
0
Elid Garazlic

数値を丸めるために、この関数を作成しました。値は文字列(例: '1.005')またはデフォルトで1になる数値1.005で、小数を2に指定すると結果は1.01になります

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

使用法:round(1.005、2)// 1.01または使用法:round( '1.005'、2)//1.01

0
chriscrossweb

Brian Ustasのソリューションを使用する:

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

この答えはスピードに関するものです。

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 これについて.

0
aleha

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