Help us understand the problem. What is going on with this article?

【JavaScript】桁指定して四捨五入・切り上げ・切り捨て

そんなの誰でも知ってるよって声が聞こえてきそうですが、自分がはまったことを晒すのは人の時間の節約に繋がるはずと信じて。

【注】結論だけ見たい人は、一番下まですっ飛んでいってください。

JavaScriptで用意されている関数

まず単純な四捨五入、切り上げ、切り捨てから。

const value = 123.45
console.log("四捨五入: " + Math.round(value))
console.log("切り上げ: " + Math. ceil(value))
console.log("切り捨て: " + Math. floor(value))
四捨五入: 123
切り上げ:124
切り捨て:123

残念な所としては、少数点第一位で処理して整数になるところでしょうか。
融通が効かない子で、これ以外やってくれません。

任意の桁で行うには?

ここでは、1の位でやってみます。

const value = 123.45
console.log("四捨五入: " + Math.round(value/10)*10)
console.log("切り上げ: " + Math. ceil(value/10)*10)
console.log("切り捨て: " + Math. floor(value/10)*10)
四捨五入: 120
切り上げ: 130
切り捨て: 120

上手くいきました。少数点第1位で処理されることを逆手にとって、10で割って少数点をずらした後、結果に10を掛けることで再び元の位に戻したというものです。

関数にしておこう!

ここでは四捨五入を例にしてみます。

function round(value, base) {
  return Math.round(value / base) * base
}

これで123.5を手に

console.log("四捨五入: " + round(123.456, 0.1))
四捨五入: 123.5

無事に成功!

ついでに123.46も

console.log("四捨五入: " + round(123.456, 0.01))
四捨五入: 123.46000000000001

なんか様子が違います。バグってませんか?JavaScriptさん状態。

何故なのか【飛んできた人、ここだけ読んでください】

原因は、JavaScriptの浮動小数の計算に丸め誤差があることを忘れてしまっています。
2進数を用いた近似値で計算している弊害のようです。

せっかくMath.round()で計算したあとで、0.01という少数を再び計算に参加させていますね。

試しに以下のようなテストをしてみます。

function round(value, base) {
  return Math.round(value / base) * base;
}
function round2(value, base) {
  return Math.round(value * base) / base;
}
console.log("四捨五入: " + round(123.456, 0.01))
console.log("四捨五入: " + round2(123.456, 100))

この処理は脳内では同じになるのですが、実際にやると

四捨五入: 123.46000000000001
四捨五入: 123.46

こうなります。

車輪の再発明をしても仕方ないので、万能な?round関数の自作は差し控えたいと思います...

まだもう一段?間違いを犯しているかも知れませんが、お気づきの点がありましたら、やさしく教えてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした