84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
|
export module NumberEx {
|
|||
|
|
|||
|
/**
|
|||
|
* 检测数字是否越界,如果越界给出提示
|
|||
|
* @param {*number} num 输入数
|
|||
|
*/
|
|||
|
function checkBoundary(num: number) {
|
|||
|
if (_boundaryCheckingState) {
|
|||
|
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
|
|||
|
console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 精确乘法
|
|||
|
*/
|
|||
|
export function times(num1: number, num2: number, ...others: number[]): number {
|
|||
|
if (others.length > 0) {
|
|||
|
return times(times(num1, num2), others[0], ...others.slice(1));
|
|||
|
}
|
|||
|
const num1Changed = num1.Float2Fixed();
|
|||
|
const num2Changed = num2.Float2Fixed();
|
|||
|
const baseNum = num1.DigitLength() + num2.DigitLength();
|
|||
|
const leftValue = num1Changed * num2Changed;
|
|||
|
|
|||
|
checkBoundary(leftValue);
|
|||
|
|
|||
|
return leftValue / Math.pow(10, baseNum);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 精确加法
|
|||
|
*/
|
|||
|
export function plus(num1: number, num2: number, ...others: number[]): number {
|
|||
|
if (others.length > 0) {
|
|||
|
return plus(plus(num1, num2), others[0], ...others.slice(1));
|
|||
|
}
|
|||
|
const baseNum = Math.pow(10, Math.max(num1.DigitLength(), num2.DigitLength()));
|
|||
|
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 精确减法
|
|||
|
*/
|
|||
|
export function minus(num1: number, num2: number, ...others: number[]): number {
|
|||
|
if (others.length > 0) {
|
|||
|
return minus(minus(num1, num2), others[0], ...others.slice(1));
|
|||
|
}
|
|||
|
const baseNum = Math.pow(10, Math.max(num1.DigitLength(), num2.DigitLength()));
|
|||
|
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 精确除法
|
|||
|
*/
|
|||
|
export function divide(num1: number, num2: number, ...others: number[]): number {
|
|||
|
if (others.length > 0) {
|
|||
|
return divide(divide(num1, num2), others[0], ...others.slice(1));
|
|||
|
}
|
|||
|
const num1Changed = num1.Float2Fixed();
|
|||
|
const num2Changed = num2.Float2Fixed();
|
|||
|
checkBoundary(num1Changed);
|
|||
|
checkBoundary(num2Changed);
|
|||
|
return times((num1Changed / num2Changed), Math.pow(10, num2.DigitLength() - num1.DigitLength()));
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 四舍五入
|
|||
|
*/
|
|||
|
export function round(num: number, ratio: number): number {
|
|||
|
const base = Math.pow(10, ratio);
|
|||
|
return divide(Math.round(times(num, base)), base);
|
|||
|
}
|
|||
|
|
|||
|
let _boundaryCheckingState = false;
|
|||
|
/**
|
|||
|
* 是否进行边界检查
|
|||
|
* @param flag 标记开关,true 为开启,false 为关闭
|
|||
|
*/
|
|||
|
function enableBoundaryChecking(flag = true) {
|
|||
|
_boundaryCheckingState = flag;
|
|||
|
}
|
|||
|
}
|