戻る

toFixed
toFixedと浮動小数誤差

(1) toFixedのみで実行した結果
(2) 誤差を抑えた実装方法

[サンプル]
copy
//[test1]
console.log( (1.234).toFixed(2) );//1.23
console.log( (1.235).toFixed(2) );//1.24
console.log( (1.245).toFixed(2) );//1.25
console.log( (1.255).toFixed(2) );//1.25
console.log( (1.005).toFixed(2) );//1.00

//[test2]
function roundTo(value, digits = 0)
{
  const factor = 10 ** digits;
  const shifted = Number((value * factor).toFixed(12));
  return Math.round(shifted) / factor;
}

console.log(roundTo(1.005, 2));   //1.01
console.log(roundTo(1.335, 2));   //1.34
console.log(roundTo(1234.567, 0));//1235
console.log(roundTo(-1.005, 2));  //-1

//[test3]
function roundToSafe(value, digits = 0) 
{
  const factor = Math.pow(10, digits);
  return Math.round((value + Number.EPSILON) * factor) / factor;
}

console.log(roundToSafe(1.005, 2)); //1.01
console.log(roundToSafe(1.235, 2)); //1.24
toFixed
四捨五入
(1) 0.5 以上なら切り上げ、未満なら切り捨て
(2) 0.5ちょうどの場合も常に切り上げ

浮動小数点による誤差
JavaScript の数値は IEEE 754 の倍精度浮動小数です。
内部表現が 1.004999… のように僅かに小さいと「2桁目の次が4に見える」ため、「1.00」と丸め下げられることがあります。
そのため、結果が「1.01」ではなく「1.00」になることがあります。
JavaScript に限らず、二進数表現を使用している方法に同様のことがいえます。

返り値が文字列のケース
計算に使うときは parseFloat や Number() で数値に戻して使ってください。

function roundTo(value, digits = 0)
誤差を吸収してから「整数に丸めて」元に戻す方法で実行する方法です。
余分に 12桁程度を固定小数にしてから丸めると安定します。

[考え方]
(1) 値を10乗倍します。
(2) 十分な桁で固定小数化して誤差吸収します。
(3) Math.roundで整数化します。
(4) 10乗で割り戻します。
※toFixed(12) の「12」は余裕をもたせ、安全に実行するためとなります。

function roundToSafe(value, digits = 0)
Math.round()のみで実行すると誤差が生じる可能性があるようです。
Number.EPSILON(極小値)を加算して補正できます。
Number.EPSILONは1と1より大きい最小の浮動小数の差(約 2.22e-16)で、境界値誤差の回避として利用しています。





戻る


著作権情報
ホームページおよプリ等に掲載されている情報等については、いかなる保障もいたしません。
ホームページおよびアプリ等を通じて入手したいかなる情報も複製、販売、出版または使用させたり、
または公開したりすることはできません。
当方は、ホームペーよびアプリ利用したいかなる理由によっての障害等が発生しても、
その結果ホームページおよびアプリ等を利用された本人または他の第三者が被った損害について
一切の責任を負わないものとします。