Math.round() 関数は、引数として与えた数を四捨五入して、もっとも近似の整数を返します。

ただし上の例では、浮動小数点数の計算に起因する四捨五入の誤差が生じます。1.005 の四捨五入で予測される結果は 1.01 ですが、戻る値は 1 です。

precisionRound(1.050, 1); // 予測 1.1、結果 1.1 (正しい)
precisionRound(1.005, 2); // 予測 1.01、結果 1 (誤り)

提案された解決策として、よりよい解決策 の章をご覧ください。

よりよい解決策

引数 precision は正の値 1 であれば小数第一未満を四捨五入、-1 であれば十の位未満を四捨五入することで、PHP や Excel と同じように働きます。

function round(number, precision) {
  var shift = function (number, precision, reverseShift) {
    if (reverseShift) {
      precision = -precision;
    }  
    var numArray = ("" + number).split("e");
    return +(numArray[0] + "e" + (numArray[1] ? (+numArray[1] + precision) : precision));
  };
  return shift(Math.round(shift(number, precision, false)), precision, true);
}

この提案策は、浮動小数点数の計算の問題を回避します。始めに、指定された precision を基にして小数部を整数部に移動します。そして、Math.round() を使用して四捨五入します。最後に、指定された precision を基にして、整数部の値を逆方向に動かして小数に戻します。

提案策を明快かつわかりやすくするため、内部の処理を以下に示します。

round(1.005, 2);
1.005 // 2桁左へ移動
100.5 // Math.round()
101   // 2桁右へ移動
1.01  // result

評価結果

round(1.050, 1); // 予測 1.1、結果 1.1  (正しい)
round(1.005, 2); // 予測 1.01、結果 1.01 (正しい)

round(3456.3456,  3); // 3456.346
round(3456.3456,  2); // 3456.35
round(3456.3456,  1); // 3456.3
round(3456.3456,  0); // 3456
round(3456.3456, -1); // 3460
round(3456.3456, -2); // 3500
round(3456.3456, -3); // 3000

round(undefined, 1        ); // NaN
round(null     , 1        ); // NaN
round("a"      , 1        ); // NaN
round(1        , null     ); // NaN
round(1        , undefined); // NaN
round(1        , "a"      ); // NaN

構文

Math.round(x)

引数

x
数値

戻り値

与えられた値をもっとも近似の整数に四捨五入した値。

説明

引数の小数部分が 0.5 以上の場合、その引数は、次に大きい整数に切り上げられます。引数の小数部分が 0.5 未満の場合、その引数は、次に小さい整数に切り下げられます。小数部分が 0.5 である場合は、正の無限大の方向で次の整数に丸められます。これは多くの言語の round() 関数と異なることに注意してください。この場合はたいてい、0 から遠ざかる次の整数に丸められます (小数部分が 0.5 である負の値を四捨五入する場合に、結果が変わります)。

round()Math オブジェクトの静的なメソッドなので、自ら生成した Math オブジェクトのメソッドとしてではなく、常に、Math.round() として使用するようにしてください (Math のコンストラクターはありません)。

Math.round( 20.49); //  20
Math.round( 20.5);  //  21
Math.round( 42  );  //  42
Math.round(-20.5);  // -20
Math.round(-20.51); // -21

小数の端数処理

// Closure
(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 (value === null || 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 -- round works towards +∞ when in-between two values
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1);      // -50 -- round works towards +∞ when in-between two values
Math.round10(-55.1, 1);    // -60
Math.round10(1.005, -2);   // 1.01 -- compare this with Math.round(1.005*100)/100 above
Math.round10(-1.005, -2);  // -1.0 -- round works towards +∞ when exactly in-between two values
// Floor
Math.floor10(55.59, -1);   // 55.5
Math.floor10(59, 1);       // 50
Math.floor10(-55.51, -1);  // -55.6 -- floor is always lower than or equal to floored number: -55.6 < -55.51
Math.floor10(-51, 1);      // -60 -- ditto
// Ceil
Math.ceil10(55.51, -1);    // 55.6
Math.ceil10(51, 1);        // 60
Math.ceil10(-55.59, -1);   // -55.5 -- ceil is always equal or above ceiled number: -55.5 > -55.59
Math.ceil10(-59, 1);       // -59 -- ditto

PHP ライクな四捨五入

以下のコードは、精度の引数を持つ独自の Math.round を自身の名前空間に追加するために使用できます。前出の小数を四捨五入する例とは異なり、こちらは文字列との変換を行いません。引数 precision は正の値 1 であれば小数第一未満を四捨五入、-1 であれば十の位未満を四捨五入することで、PHP や Excel と同じように働きます。

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

ただし上の例では、浮動小数点数の計算に起因する四捨五入の誤差が生じます。1.005 の四捨五入で予測される結果は 1.01 ですが、戻る値は 1 です。

myNamespace.round(1.050, 1); // 予測 1.1、結果 1.1 (正しい)
myNamespace.round(1.005, 2); // 予測 1.01、結果 1 (誤り)

提案された解決策として、よりよい解決策 の章をご覧ください。

仕様

仕様書 策定状況 コメント
ECMAScript 1st Edition (ECMA-262) 標準 初期定義。JavaScript 1.0 で実装。
ECMAScript 5.1 (ECMA-262)
Math.round の定義
標準  
ECMAScript 2015 (6th Edition, ECMA-262)
Math.round の定義
標準  
ECMAScript Latest Draft (ECMA-262)
Math.round の定義
ドラフト  

ブラウザー実装状況

機能ChromeEdgeFirefoxInternet ExplorerOperaSafari
基本対応 あり あり1 あり あり あり
機能Android webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
基本対応 あり あり あり4 あり あり あり

関連情報

ドキュメントのタグと貢献者

このページの貢献者: yyss, teoli, ethertank, Potappo, Kozawa
最終更新者: yyss,