import { isNaN, round, toNumber } from 'ut2';
/**
* 最大公约数,使用辗转相除法。
*
* 遵循以下约定:
*
* 1. 如果参数中包含无效数值,返回 `NaN` 。
* 2. 如果全部参数都为 `0` ,返回 `0` 。
* 3. 如果参数包含 `0` ,仅计算非零的数。
* 4. 如果参数为负数,将转为绝对值的正数。
* 5. 如果参数包含小数点,将转为四舍五入的整数。
*
* @alias module:Math.gcd
* @since 4.20.0
* @see {@link https://baike.baidu.com/item/最大公约数 | 最大公约数}
* @param {...(number|string)} nums 两个或多个整数。
* @returns {number} 最大公约数。
* @example
*
* gcd(8, 14); // 2
* gcd(57, 48); // 3
* gcd(140, 21, 42); // 7
* gcd('foo', 'bar'); // NaN
* gcd(0, 10); // 10
* gcd(2.3, 3.8, 8, -10); // 2
*
*/
function gcd(...nums) {
let num1 = nums[0];
let num2 = nums[1] === void 0 ? 0 : nums[1];
const rest = nums.slice(2);
if (rest.length > 0) {
// eslint-disable-next-line prefer-spread
return gcd.apply(void 0, [gcd(num1, num2)].concat(rest));
}
num1 = Math.abs(round(num1));
num2 = Math.abs(round(num2));
// 兼容处理,如果参数包含无效数值时,返回 NaN
if (isNaN(num1) || isNaN(num2)) {
return Number.NaN;
}
if (num1 === 0 && num2 === 0) {
return 0;
}
if (num1 === 0) {
return num2;
}
if (num2 === 0) {
return num1;
}
let temp = num2;
if (num1 < num2) {
temp = num1;
num1 = num2;
num2 = temp;
}
while (temp) {
temp = num1 % num2;
num1 = num2;
num2 = temp;
}
return toNumber(num1);
}
export default gcd;