UNPKG

wsemi

Version:

A support package for web developer.

173 lines (158 loc) 4.42 kB
import Decimal from 'decimal.js' import get from 'lodash-es/get.js' import isnum from './isnum.mjs' import isbol from './isbol.mjs' import preciseNum from './preciseNum.mjs' function gte(x1, x2) { return new Decimal(x1).gte(x2) } function gt(x1, x2) { return new Decimal(x1).gt(x2) } function lte(x1, x2) { return new Decimal(x1).lte(x2) } function lt(x1, x2) { return new Decimal(x1).lt(x2) } function eq(x1, x2) { return new Decimal(x1).eq(x2) } function neq(x1, x2) { return !eq(x1, x2) } /** * 使用指定條件判斷兩數字成立與否 * * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/judge.test.mjs Github} * @memberOf wsemi * @param {String|Number} x1 輸入數字字串或數字,若要精準判識得要用字串 * @param {String} op 輸入操作符號字串,可使用'===''!==''>=''<=''>''<' * @param {NuString|Number} x2 輸入數字字串或數字,若要精準判識得要用字串 * @param {Object} [opt={}] 輸設定物件,預設{} * @param {Boolean} [opt.withPreciseNum=true] 輸是否自動轉原始精度之數字字串布林值,預設true * @returns {Number} 回傳判斷布林值 * @example * * let x1 * let op * let x2 * let b * * x1 = 0 * op = '>=' * x2 = 0 * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 0, '>=', 0 true * * x1 = 1 * op = '>=' * x2 = 1 * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 1, '>=', 1 true * * //浮點數誤差 * x1 = 0.3 * op = '>=' * x2 = 0.1 + 0.2 * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 0.3, '>=', 0.30000000000000004 false * * x1 = 0.3 * op = '>=' * x2 = 0.1 + 0.2 * b = judge(x1, op, x2, { withPreciseNum: true }) //default * console.log(`${x1}, '${op}', ${x2}`, b) * // => 0.3, '>=', 0.30000000000000004 true * * x1 = 0.3 * op = '>=' * x2 = Decimal.sum(0.1, 0.2).toString() * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 0.3, '>=', 0.3 true * * x1 = Decimal.sum(0.1, 0.2).toString() * op = '>=' * x2 = 0.3 * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 0.3, '>=', 0.3 true * * //加法順序會導致不同的誤差 * x1 = 4.67 + 7.12 + 94.4 * op = '>=' * x2 = 94.4 + 7.12 + 4.67 * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 106.19, '>=', 106.19000000000001 false * * x1 = 4.67 + 7.12 + 94.4 * op = '>=' * x2 = 94.4 + 7.12 + 4.67 * b = judge(x1, op, x2, { withPreciseNum: true }) //default * console.log(`${x1}, '${op}', ${x2}`, b) * // => 106.19, '>=', 106.19000000000001 true * * x1 = Decimal.sum(4.67, 7.12, 94.4).toString() * op = '>=' * x2 = Decimal.sum(94.4, 7.12, 4.67).toString() * b = judge(x1, op, x2, { withPreciseNum: false }) * console.log(`${x1}, '${op}', ${x2}`, b) * // => 106.19, '>=', 106.19 true * */ function judge(x1, op, x2, opt = {}) { //check if (!isnum(x1)) { throw new Error(`x1 is not a number`) } if (!isnum(x2)) { throw new Error(`x2 is not a number`) } //withPreciseNum let withPreciseNum = get(opt, 'withPreciseNum') if (!isbol(withPreciseNum)) { withPreciseNum = true } //preciseNum if (withPreciseNum) { x1 = preciseNum(x1) x2 = preciseNum(x2) } if (op === '===') { if (x1 === x2) { //預先判斷可加速 return true } return eq(x1, x2) } else if (op === '!==') { return neq(x1, x2) } else if (op === '>=') { if (x1 === x2) { //預先判斷可加速 return true } return gte(x1, x2) } else if (op === '>') { return gt(x1, x2) } else if (op === '<=') { if (x1 === x2) { //預先判斷可加速 return true } return lte(x1, x2) } else if (op === '<') { return lt(x1, x2) } else { console.log(op) throw new Error(`invalid op[${op}]`) } } export default judge