动态改变变量类型
Dynamically changing variables type
我正在构建一个分解程序,我想在 number <= Number.MAX_SAFE_INTEGER
.
时将每个 BigInt
类型更改为常规 Numbers
不用为每种情况编写两个函数,如果我可以将它们全部放在一个函数中,该函数可以相应地改变变量类型,那就太好了 (某事像 let myVar = 3n || 3
我猜).
function Factorize(dividend) {
let divisor = 2n;
//if number <= Number.MAX_SAFE_INTEGER then let divisor = 2. Same for all other bigInts.
let method1 = [], method2 = [];
while (dividend > 1n) {
if (dividend % divisor === 0n) {
method1.push(`${divisor}`);
method2.push(`${dividend} / ${divisor}`);
dividend /= divisor;
} else {
divisor++
};
};
return {
default: method1,
detailed: method2,
get isPrime() {
return this.default.length === 1 && this.default[0] !== 2;
}
};
};
const number = parseInt(prompt());
console.log(Factorize(BigInt(number)));
感谢您的帮助。
有什么困难?您的评论已包含所需代码的一半:
if (dividend <= Number.MAX_SAFE_INTEGER) {
divisor = 2;
dividend = Number(dividend);
}
然后你只需要将两个严格相等比较 === 0n
和 !== 2
替换为它们的非严格变体。 0 == 0n
returns true
, 0n === 0n
returns false.
其他一些值得一提的事情:
(1) 这种因式分解方法非常慢。有远低于 Number.MAX_SAFE_INTEGER
的素数,这将需要 个月 。根据您的用例,限制输入大小或实施某种超时(例如,如果一定数量的迭代不足以找到完整结果则返回错误)可能比支持 BigInts 更重要。 (对于只有小素因子的输入,即使是非常大的输入仍然会很快终止,所以肯定有可能超过 Number 范围(甚至 Number.MAX_VALUE
),而仍然只需要几毫秒。)
(2) 使用 parseInt
获取输入意味着您将自己限制在数字精度上;之后将该 Number 转换为 BigInt 不会恢复丢失的位。例如,如果有人输入 '12157665459056928801'
(即 3n ** 40n),parseInt
将截断它,因此您的程序将计算出错误的结果。为避免这种情况,请使用 BigInt()
构造函数可以直接转换字符串的事实,即:BigInt(prompt())
.
(3) 虽然有时可以编写同时适用于 Numbers 和 BigInts 的代码,但通常不建议这样做(通常甚至没有用),因为这两种类型的值(故意!)表现不同在很多方面(否则我们不需要它们),所以这样的代码很可能没有按照你认为的那样去做。在这种特殊情况下应该没问题;我只是建议不要从这个例子中概括。
我正在构建一个分解程序,我想在 number <= Number.MAX_SAFE_INTEGER
.
BigInt
类型更改为常规 Numbers
不用为每种情况编写两个函数,如果我可以将它们全部放在一个函数中,该函数可以相应地改变变量类型,那就太好了 (某事像 let myVar = 3n || 3
我猜).
function Factorize(dividend) {
let divisor = 2n;
//if number <= Number.MAX_SAFE_INTEGER then let divisor = 2. Same for all other bigInts.
let method1 = [], method2 = [];
while (dividend > 1n) {
if (dividend % divisor === 0n) {
method1.push(`${divisor}`);
method2.push(`${dividend} / ${divisor}`);
dividend /= divisor;
} else {
divisor++
};
};
return {
default: method1,
detailed: method2,
get isPrime() {
return this.default.length === 1 && this.default[0] !== 2;
}
};
};
const number = parseInt(prompt());
console.log(Factorize(BigInt(number)));
感谢您的帮助。
有什么困难?您的评论已包含所需代码的一半:
if (dividend <= Number.MAX_SAFE_INTEGER) {
divisor = 2;
dividend = Number(dividend);
}
然后你只需要将两个严格相等比较 === 0n
和 !== 2
替换为它们的非严格变体。 0 == 0n
returns true
, 0n === 0n
returns false.
其他一些值得一提的事情:
(1) 这种因式分解方法非常慢。有远低于 Number.MAX_SAFE_INTEGER
的素数,这将需要 个月 。根据您的用例,限制输入大小或实施某种超时(例如,如果一定数量的迭代不足以找到完整结果则返回错误)可能比支持 BigInts 更重要。 (对于只有小素因子的输入,即使是非常大的输入仍然会很快终止,所以肯定有可能超过 Number 范围(甚至 Number.MAX_VALUE
),而仍然只需要几毫秒。)
(2) 使用 parseInt
获取输入意味着您将自己限制在数字精度上;之后将该 Number 转换为 BigInt 不会恢复丢失的位。例如,如果有人输入 '12157665459056928801'
(即 3n ** 40n),parseInt
将截断它,因此您的程序将计算出错误的结果。为避免这种情况,请使用 BigInt()
构造函数可以直接转换字符串的事实,即:BigInt(prompt())
.
(3) 虽然有时可以编写同时适用于 Numbers 和 BigInts 的代码,但通常不建议这样做(通常甚至没有用),因为这两种类型的值(故意!)表现不同在很多方面(否则我们不需要它们),所以这样的代码很可能没有按照你认为的那样去做。在这种特殊情况下应该没问题;我只是建议不要从这个例子中概括。