StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.1 KiB
86 lines
2.1 KiB
4 years ago
|
type Operator = '+' | '-' | '*' | '/' | '%'
|
||
|
|
||
|
/**
|
||
|
* For any precise floating point calculation
|
||
|
*
|
||
|
* @export
|
||
|
* @class Decimal
|
||
|
*/
|
||
|
export default class Decimal {
|
||
|
num: number
|
||
|
|
||
|
constructor(num: number) {
|
||
|
this.num = num
|
||
|
}
|
||
|
|
||
|
decimal(num2: number, operator: Operator): this {
|
||
|
const num1 = this.num
|
||
|
const len1 = this.getDecimalLen(num1)
|
||
|
const len2 = this.getDecimalLen(num2)
|
||
|
let base = 0
|
||
|
switch (operator) {
|
||
|
case '+':
|
||
|
base = this.getExponent(len1, len2)
|
||
|
this.num = (this.safeRoundUp(num1, base) + this.safeRoundUp(num2, base)) / base
|
||
|
break
|
||
|
case '-':
|
||
|
base = this.getExponent(len1, len2)
|
||
|
this.num = (this.safeRoundUp(num1, base) - this.safeRoundUp(num2, base)) / base
|
||
|
break
|
||
|
case '*':
|
||
|
this.num =
|
||
|
this.safeRoundUp(
|
||
|
this.safeRoundUp(num1, this.getExponent(len1)),
|
||
|
this.safeRoundUp(num2, this.getExponent(len2)),
|
||
|
) / this.getExponent(len1 + len2)
|
||
|
break
|
||
|
case '/':
|
||
|
base = this.getExponent(len1, len2)
|
||
|
this.num = this.safeRoundUp(num1, base) / this.safeRoundUp(num2, base)
|
||
|
break
|
||
|
case '%':
|
||
|
base = this.getExponent(len1, len2)
|
||
|
this.num = (this.safeRoundUp(num1, base) % this.safeRoundUp(num2, base)) / base
|
||
|
break
|
||
|
}
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
plus(num2: number) {
|
||
|
return this.decimal(num2, '+')
|
||
|
}
|
||
|
|
||
|
minus(num2: number) {
|
||
|
return this.decimal(num2, '-')
|
||
|
}
|
||
|
|
||
|
multiply(num2: number) {
|
||
|
return this.decimal(num2, '*')
|
||
|
}
|
||
|
|
||
|
divide(num2: number) {
|
||
|
return this.decimal(num2, '/')
|
||
|
}
|
||
|
|
||
|
remainder(num2: number) {
|
||
|
return this.decimal(num2, '%')
|
||
|
}
|
||
|
|
||
|
toNumber(): number {
|
||
|
return this.num
|
||
|
}
|
||
|
|
||
|
private getDecimalLen(num: number): number {
|
||
|
return (`${num}`.split('.')[1] || '').length
|
||
|
}
|
||
|
|
||
|
private getExponent(num1: number, num2?: number): number {
|
||
|
return Math.pow(10, num2 !== void 0 ? Math.max(num1, num2) : num1)
|
||
|
}
|
||
|
|
||
|
// fix: 9999999.99995 * 100000 = 999999999994.9999
|
||
|
private safeRoundUp(num: number, exponent: number): number {
|
||
|
return Math.round(num * exponent)
|
||
|
}
|
||
|
}
|