【问题标题】:Dynamically changing variables type动态变化的变量类型
【发布时间】:2021-12-29 12:52:30
【问题描述】:

我正在构建一个分解程序,我想在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)));

感谢您的帮助。

【问题讨论】:

    标签: javascript numbers bigint


    【解决方案1】:

    有什么困难?您的评论已经包含了一半的必需代码:

      if (dividend <= Number.MAX_SAFE_INTEGER) {
        divisor = 2;
        dividend = Number(dividend);
      }
    

    然后您只需将=== 0n!== 2 这两个严格相等比较替换为它们的非严格变体。 0 == 0n 返回 true0n === 0n 返回 false。

    还有一些值得一提的:

    (1) 这种分解方法非常慢。有远低于Number.MAX_SAFE_INTEGER 的素数,这需要个月。根据您的用例,限制输入大小或实现某种超时(例如,如果一定数量的迭代不足以找到完整的结果,则返回错误)可能比支持 BigInts 更重要。 (对于只有小的素因数的输入,即使是非常大的输入仍然会很快终止,因此肯定有可能超过数字范围(甚至Number.MAX_VALUE),而仍然只需要几毫秒。)

    (2) 使用parseInt 获取您的输入意味着您将自己限制为数字精度;之后将该 Number 转换为 BigInt 并不会带回丢失的位。例如,如果有人输入 '12157665459056928801'(即 3n ** 40n),parseInt 将截断它,您的程序将因此计算错误的结果。为避免这种情况,请使用 BigInt() 构造函数可以直接转换字符串的事实,即:BigInt(prompt())

    (3) 虽然有时可以编写同时适用于 Numbers 和 BigInts 的代码,但通常不建议这样做(而且通常甚至没有用),因为这两种类型的值(故意!)在方法的数量(否则我们将不需要它们),因此此类代码很有可能无法执行您认为会执行的操作。在这种特殊情况下,应该没问题;我只是建议不要从这个例子中一概而论。

    【讨论】:

    • 能否请您在说“这种分解方法非常慢”时澄清一下。你有什么建议吗?我在stackoverflow上查找了用js编写的分解算法,这个是最快的。
    • 尝试 99999989、999999929、9999999929,您会看到:预计大约 2 秒、20 秒、3 分钟,具体取决于您的硬件;这只是 8-10 位十进制数字。每个数字将乘以 10,MAX_SAFE_INTEGER 有 16 个数字。素数分解是一个计算困难的问题。许多密码学方案都依赖于此。您可以通过尝试更少的候选人来节省一些时间,例如跳过所有偶数(当然2 除外),当divisor**2&gt;dividend 时停止。还有概率素性检验,例如Miller-Rabin,它可以告诉你什么时候尝试分解是没有意义的。
    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多