12.8.2. Fraction¶
12.8.2.1. 概要¶
カスタムスクリプト内では、JavaScript と同じ精度で計算が行われるため、通常の計算では誤差が生じることがあります。
例えば、カスタムスクリプトで 0.1 + 0.2 や 1 - 0.9 を計算すると誤差が生じます。
const result1 = 0.1 + 0.2;
console.log(result1); // => 0.30000000000000004
const result2 = 1 - 0.9;
console.log(result2); // => 0.09999999999999998
高精度小数を Fraction クラスで扱うことで、内部的に分数として取り扱い、誤差を極力小さくした小数の計算ができます。
上記例の 0.1 + 0.2 および 1 - 0.9 を正しく計算するには、以下のように記述します。
const result1 = new Fraction(0.1).add(new Fraction(0.2));
console.log(result1.toNumber()); // => 0.3
const result2 = new Fraction(1).sub(new Fraction(0.9));
console.log(result2.toNumber()); // => 0.1
変数が「高精度小数」型で指定されている場合、カスタムスクリプトでは Fraction 型の値が取得されます。
注意
仕様上の注意点
Fraction が扱える最大数値と最小数値は、JavaScript の number 型と同一です。 BigDecimal ではないため、非常に大きい数値や限りなく 0 に近い数値は、number 同様に取り扱えません。
金額の計算など、厳密な精度での計算が求められる場合は、Fraction を使用せず、サーバ側で計算処理を行ってください。
12.8.2.2. Fraction クラス¶
Fraction は、IFraction インタフェースを持つ IM-BloomMaker 独自のクラスです。 IM-BloomMaker のカスタムスクリプトで高精度小数を扱うときは Fraction クラスを利用できます。
コンストラクタの引数には以下のいずれかを指定してください。
// 数値で初期化する場合
const a = new Fraction(0.5);
// 文字列で初期化する場合
const b = new Fraction('0.5');
// 分子(第1引数)・分母(第2引数)で初期化する場合
const c = new Fraction(1, 2);
12.8.2.3. Fraction で使用可能なプロパティ¶
Fraction には以下のプロパティを持ちます。 プロパティは全て読み取り専用です。
- numerator
- 分子
- denominator
- 分母
- plus
- 正の数の場合は true、それ以外の場合は false
- zero
- ゼロの場合は true、それ以外の場合は false
- minus
- 負の数の場合は true、それ以外の場合は false
- divisible
- 割り切れる数の場合は true、それ以外の場合は false
12.8.2.4. Fraction で使用可能な関数¶
Fraction クラスの値を使って計算を行う場合は、以下の演算用関数を使用します。 以下は、利用できる関数の一覧です。
- toString()
オブジェクトが持つ値を文字列型に変換して返却します。 割り切れない数の場合、分数表記で返却されます。const a = new Fraction(3).toString(); console.log(a); // => "3" const b = new Fraction(1, 3).toString(); console.log(b); // => "1/3"
- toNumber()
オブジェクトが持つ値を数値型に変換して返却します。 桁落ちにより精度が落ちますので注意してください。const a = new Fraction(3).toNumber(); console.log(a); // => 3 const b = new Fraction(1, 3).toNumber(); console.log(b); // => 0.3333333333333333
- clone()
オブジェクトのインスタンスを複製します。console.log(a.toNumber()); // => 3 const b = a.clone(); console.log(b.toNumber()); // => 3
- equals()
関数の引数に与えられた Fraction オブジェクトの値と一致するか判定します。const a = new Fraction(0.5); const result1 = a.equals(new Fraction(1, 2)); console.log(result1); // => true const result2 = a.equals(new Fraction(1)); console.log(result2); // => false
- compare()
関数の引数に与えられた Fraction オブジェクトの値との差分比較を行います。const a = new Fraction(3); const result = a.compare(new Fraction(5)); console.log(result); // => -2
- add()
関数の引数に与えられた数値を加算して返却します。第1引数に分子、または、Fraction オブジェクトを指定し、第2引数に分母を指定してください。第2引数が省略された場合は 1 が使用されます。const a = new Fraction(1); const result1 = a.add(2); console.log(result1.toNumber()); // => 3 const b = new Fraction(1, 2); const result2 = b.add(3, 2); console.log(result2.toNumber()); // => 2
- sub()
関数の引数に与えられた数値を減算して返却します。第1引数に分子、または、Fraction オブジェクトを指定し、第2引数に分母を指定してください。第2引数が省略された場合は 1 が使用されます。const a = new Fraction(5); const result1 = a.sub(3); console.log(result1.toNumber()); // => 2 const b = new Fraction(3, 2); const result2 = b.sub(1, 2); console.log(result2.toNumber()); // => 1
- mul()
関数の引数に与えられた数値を乗算して返却します。第1引数に分子、または、Fraction オブジェクトを指定し、第2引数に分母を指定してください。第2引数が省略された場合は 1 が使用されます。const a = new Fraction(2); const result1 = a.mul(3); console.log(result1.toNumber()); // => 6 const b = new Fraction(6); const result2 = b.mul(1, 3); console.log(result2.toNumber()); // => 2
- div()
関数の引数に与えられた数値で除算した結果を返却します。第1引数に分子、または、Fraction オブジェクトを指定し、第2引数に分母を指定してください。第2引数が省略された場合は 1 が使用されます。const a = new Fraction(4); const result1 = a.div(2); console.log(result1.toNumber()); // => 2 const b = new Fraction(2); const result2 = b.div(1, 2); console.log(result2.toNumber()); // => 4
- mod()
関数の引数に与えられた数値で除算した余りを返却します。第1引数に分子、または、Fraction オブジェクトを指定し、第2引数に分母を指定してください。第2引数が省略された場合は 1 が使用されます。const a = new Fraction(5); const result1 = a.mod(2); console.log(result1.toNumber()); // => 1 const b = new Fraction(5); const result2 = b.mod(3, 2); console.log(result2.toNumber()); // => 0.5
- abs()
オブジェクトが持つ値の絶対値を返却します。const a = new Fraction(-3); const result = a.abs(); console.log(result.toNumber()); // => 3
- floor()
オブジェクトが持つ値を、小数点以下を切り捨てて返却します。const a = new Fraction(1.23); const result = a.floor(); console.log(result); // => 1round()
オブジェクトが持つ値を、小数点以下を四捨五入して返却します。const a = new Fraction(1.23); const result1 = a.round(); console.log(result1); // => 1 const b = new Fraction(1.56); const result2 = b.round(); console.log(result2); // => 2ceil()
オブジェクトが持つ値を、小数点以下を繰り上げて返却します。const a = new Fraction(1.23); const result = a.ceil(); console.log(result); // => 2