ツクールMVの開発で小数を計算したかったのですが、Javascriptでは小数を扱う計算で誤差が生まれてしまうんですね。
そこで、小数を誤差なく扱えるライブラリを導入しました。
今回はnumeral-jsを使ってみました。
導入方法としては、GitHubのnumeral.jsにアクセス => Raw => 名前を付けて保存 をして、ツクールMVにプラグインとして追加します。
0.1 + 0.2 // => 0.30000000000000004
numeral(0.1).add(0.2).value()// => 0.3
元々の計算式より少々書き方が煩雑にはなりますが、誤差なく計算してくれるようになりました。
メソッドを足してみる
numeral.jsには四則計算のためのメソッドとして、add, subtract, multiply, divideがそれぞれ用意されています。
足し算のadd以外は長いので、エイリアス(別名)としてメソッドを足してみました。
加えて、複数の引数を入れて一気に計算できるメソッドも追加してみました。
Object.assign(numeral.fn, {
plus: function(value){ return this.add(value) },
adds: function(...values){
for(const value of values){
this.add(value)
}
return this;
},
sub: function(value){ return this.subtract(value) },
minus: function(value){ return this.subtract(value) },
subs: function(...values){
for(const value of values){
this.subtract(value)
}
return this;
},
mult: function(value){ return this.multiply(value) },
mults: function(...values){
for(const value of values){
this.multiply(value)
}
return this;
},
div: function(value){ return this.divide(value) },
divs: function(...values){
for(const value of values){
this.divide(value)
}
return this;
}
})
numeral(0.3).sub(0.1).value()// => 0.3
//== numeral(0.3).subtract(0.1).value()// => 0.3
numeral(0.1).adds(0.2, 0.3, 0.4, 0.5).value()// => 1.5
GitHubにて配布しましたので、numeral.jsを使われる際はご自由にどうぞ
Object.assign()で関数同士を結合してみましたが、Object.defineproperties()で新たにメソッドを書くのとどちらがいいんでしょう?
他のライブラリ
小数を扱えるようにするライブラリとしては、bignumber.jsやdecimal.jsのほうが有名そうですが、RPGツクールMV1.6.2ではプラグインとして読み込んでも、うまく動作しませんでした。
new Decimal(0.1).plus(0.2)// => {constructor: Decimal(v), d:[3000000], e:-1, s:1}
//(値が返ってくるはずが、オブジェクトが返ってくる)
理由は謎です。