检测 javascript 中的无限分数

Detect infinite fraction in javascript

无限分数:1/3、2/3、饼等

非无限分数:1/2、1/5、1/10 等

我如何检测一个数字何时是无限小数?

您可以使用 JavaScript 提供的 isFinite() 函数。

有趣的问题。

认真遵循 question on math.stackexchange.com, I think the following should do the trick for an irreducible fraction 中提出的智慧:

function* primeFactors(n) {
  let divisor = 2;

  while (n >= 2) {
    if (n % divisor == 0) {
      yield divisor;
      n = n / divisor;
    } else {
      divisor++;
    }
  }
}

const isRepeating = (n, d) => {
  const fn = n % d;
  if (fn === 0) {
    return false;
  }
  return !Array.from(primeFactors(d)).every(v => v === 2 || v === 5)
}

那么,如何减少分数呢?如果将分子和分母因式分解,您可以找出它们有哪些共同因素,然后将分子和分母都除以这些共同因素。这是执行此操作的一种方法:

const counts = (arr) => {
  return arr.reduce((acc, curr) => {
    const currentCount = acc.get(curr) ?? 0;
    acc.set(curr, currentCount + 1)
    return acc;
  }, new Map())
}

const reduceFraction = (n, d) => {
  const fn = Array.from(primeFactors(n));
  const fd = Array.from(primeFactors(d));
  const countsFn = counts(fn);
  const countsFd = counts(fd);

  let rn = n;
  let rd = d;

  countsFn.forEach((count, factor) => {
    const fdCount = countsFd.get(factor) ?? 0;
    const c = Math.min(fdCount, count);
    for (let i = 0; i < c; ++i) {
      rn /= factor;
      rd /= factor;
    }
  })

  return { n: rn, d: rd }
}

所以,把这些放在一起:

function* primeFactors(n) {
  let divisor = 2;
  while (n >= 2) {
    if (n % divisor === 0) {
      yield divisor;
      n = n / divisor;
    } else {
      divisor++;
    }
  }
}
const counts = (arr) => {
  return arr.reduce((acc, curr) => {
    var _a;
    const currentCount = acc.get(curr) ?? 0;
    acc.set(curr, currentCount + 1);
    return acc;
  }, new Map());
};
const reduceFraction = (n, d) => {
  const fn = Array.from(primeFactors(n));
  const fd = Array.from(primeFactors(d));
  const countsFn = counts(fn);
  const countsFd = counts(fd);
  let rn = n;
  let rd = d;
  countsFn.forEach((count, factor) => {
    var _a;
    const fdCount = countsFd.get(factor) ?? 0;
    const c = Math.min(fdCount, count);
    for (let i = 0; i < c; ++i) {
      rn /= factor;
      rd /= factor;
    }
  });
  return {
    n: rn,
    d: rd
  };
};
const isRepeating = (num, den) => {
  const {
    n,
    d
  } = reduceFraction(num, den);
  const fn = n % d;
  if (fn === 0) {
    return false;
  }
  return !Array.from(primeFactors(d)).every(v => v === 2 || v === 5);
};

console.log(isRepeating(4, 3))
console.log(isRepeating(1, 140))
console.log(isRepeating(1, 2))
console.log(isRepeating(2, 50))
console.log(isRepeating(3, 15))

但是,请注意有时(由于 floating-point 的原因),JS 可能不同意。

const a = 0.1;
let t = 0;
for (let i = 0; i < 10; ++i) {
  t += a;
}
console.log(t)

您可以检测 32 位浮点数 after-comma 部分的最大长度。然后通过除以数字,将数字除以“。”并获得 after-comma 周期长度。如果相同或length - 1,则可能是无限小数