JavaScriptのfloorは小数点切り下げで切り捨てではない

JavaScriptのJavaScriptのfloorは小数点切り下げで切り捨てではない

JavaScriptのfloorは小数点切り下げで切り捨てではない

JavaScriptで取得した数値を整数として取得するため小数点以下を削除したいことがある。例えば12.34を12にするなどだ。

この際にfloorを使用されているケースが非常に多いのだがfloorは小数点切り捨てではなく小数点切り下げなので使用してはいけない。

小数点切り捨てと切り下げの違い

小数点切り捨てとは1.5なら1、-1.5なら-1のように小数点以下を削除することだが切り下げは指定された基準値1の倍数になるように、最も近い値に数値を切り捨てます。

そのためMath.floor(1.5)は1になりますがMath.floor(-1.5)は-2になります。

console.log(Math.floor(12.34)); // => 12
console.log(Math.floor(56.78)); // => 56
console.log(Math.floor(1.5));   // => 1
console.log(Math.floor(-0.12)); // => -1
console.log(Math.floor(-1.49)); // => -2
console.log(Math.floor(-1.5));  // => -2

負数の場合はMath.ceilを使用すればMath.ceil(-1.5)が-1となるため想定通りの結果を返すことができます。

このような結果になる理由はfloorはfloor(x) = x-(x modulo 1)になっていてJavaScriptの剰余演算の処理方法の仕様に基づくものなのですが説明が難しく長くなるため割愛。

負数の場合、Math.floor(-1.5)は-(Math.ceil(1.5))と同じ結果になるというふうに覚えれば問題ないです。(ceilはその逆)

小数点切り捨てにはMath.truncを使う

JavaScriptでの小数点切り捨てにはMath.truncを使うと便利です。Math.trunc(1.5)は1になり、Math.trunc(-1.5)は-1が返ってくるため希望通りの数値が返ります。

Math.trunc?そんなの聞いたことがないという人も多いと思いますが実はMath.truncはIE11以下では対応していないため使用されるケースが少ないのです。

なんだよ!じゃあダメじゃん!

と思われる方も多いと思いますがMath.truncが使用できない場合は下記のようにMath.floor, Math.ceilを使用する記述にすれば問題ないです。

Math.trunc = Math.trunc || function(x) {
  return x < 0 ? Math.ceil(x) : Math.floor(x);
};
console.log(Math.trunc(12.34)); // => 12
console.log(Math.trunc(56.78)); // => 56
console.log(Math.trunc(1.5));   // => 1
console.log(Math.trunc(-0.12)); // => -0
console.log(Math.trunc(-1.49)); // => -1
console.log(Math.trunc(-1.5));  // => -1

ちなみに数値の先頭にチルダ(~)を2個付けてビット反転を2回行うことでも同様の結果になるがコードの見た目が悪くなるため避けた方が良い。

console.log(~~12.34); // => 12
console.log(~~56.78); // => 56
console.log(~~1.5);   // => 1
console.log(~~-0.12); // => -0
console.log(~~-1.49); // => -1
console.log(~~-1.5);  // => -1

toFixed(0)も使用してはいけない

小数点切り捨てのためtoFixed(0)を使用しているケースもたまに見かけるがこのやり方は非常に良くない。

toFixedは四捨五入をして返してしまい、しかも結果を数値ではなく文字列として返してしまう。

console.log((12.34).toFixed(0)); // => '12'
console.log((56.78).toFixed(0)); // => '57'
console.log((1.5).toFixed(0));   // => '2'
console.log((-0.12).toFixed(0)); // => '-0'
console.log((-1.49).toFixed(0)); // => '-1'
console.log((-1.5).toFixed(0));  // => '-2'

JavaScriptのfloor, trunc, toFixedを使用したサンプル