LoginSignup
6
4

More than 5 years have passed since last update.

[JavaScript] 負数の四捨五入がExcelと合わない問題

Last updated at Posted at 2017-06-14

はじめに

背景と概要

  • 要件
    • JavaScriptを使用して小数n桁の四捨五入を行う
    • 計算結果はExcelと合わせること

JavaScriptのMathオブジェクトでは小数n桁の指定ができません。
JavaScriptライブラリを使用できない事情があり、関数を作ることにしました。

この際、負数の計算で、JavaScriptとExcelの結果に差異が発生してしまいました。
この問題を解決するまでの知見を共有します。

前提バージョン

  • ECMA Script 2015

問題点

まずは、こんなコーディングをしてみました。
数値と端数処理桁数を受け取り、四捨五入した結果を返す関数です。

JavaScript
function myRound(number, pricision) {
    var _pow = Math.pow(10, pricision);
    return Math.round(number * _pow) / _pow;
};

正の数値では期待どおり動作しましたが、負数の場合には以下のような計算結果となりました。

元の値 JavaScript Excel
-5.4 -5 -5
-5.5 -5 -6
-5.9 -6 -6

Excelの計算と異なってしまっており、要件を満たせません。

解決策と得られた知見

JavaScript(Math)とExcelでは、負数の四捨五入の仕様が異なりました。
MDN - Math.round()

すなわち0.5を丸める「向き」が、マイナス方向か、ゼロ方向かの違いです。

  • Excelはマイナス方向に丸め処理するため、-5.5 → -6
  • JavaScriptはゼロ方向に丸め処理するため、-5.5 → -5

という訳です。

コードを以下のように修正したところ、Excelと同じ計算結果となりました。

JavaScript
function myRound(number, pricision) {
    var _sign = (number < 0) ? -1 : 1;
    var _pow = Math.pow(10, pricision);
    return Math.round((number * _sign) * _pow) / _pow * _sign;
};     

負数の切り捨て・切り上げの場合も同じ原理で、JavaScriptとExcel関数では結果が異なります。
MDN - Math.floor()
MDN - Math.ceil()

なお、Javaの場合も、MathクラスとBigDecimalクラスでは負数の端数処理の向きが逆になります。
Javaの負の数の切り捨て・四捨五入にはご注意!

ということで、負数の端数処理については、「向き」に気をつけましょう!

参考にさせていただいた記事

JavaScript Math.roundをオーバーロードして小数点以下X桁を指定して四捨五入する

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4