首页 > 解决方案 > 如何验证十进制数是否在序列 0.001、0.002、...、2.048 中

问题描述

对于整数 [1, 2, 4, 8, 16, ...] 我可以使用这个函数:

const validate = num => (num & num - 1) == 0;

有没有一种优雅的类似方法可以在不使用循环的情况下使用十进制数?

并且应该可以使用基于初始值的小数点后的任意位数。

现在我使用该函数来确定小数点逗号后是否有数字并计算它们:

countDecimals(num) {
  if (Math.floor(num.valueOf()) === num.valueOf()) return 0;
  return num.toString().split(".")[1].length || 0;
}

然后我使用它:

validateEntryValue(entryValue) {
  const decimalsQuantity = this.countDecimals(entryValue);
  if (decimalsQuantity) {
    const numToMul = Math.pow(10, decimalsQuantity);
    return ((entryValue * numToMul) & (entryValue * numToMul) - 1) == 0;
  }
  return (entryValue & entryValue - 1) == 0;
}

但有些结果值未能通过测试:

标签: javascript

解决方案


请注意,使用浮点数进行数学运算可能不准确,因此验证它们(需要精确值)可能效果不佳。

因此,您可以将数字相乘,使其成为整数,以避免精度问题,然后您甚至可以在其上使用您的解决方案。

这是一个纯粹的数学解决方案:

const validate = (toVerify, initial) => {
  const num = toVerify / initial //division is like multiplication with the reciprocal!
  return (num & num - 1) == 0
};

console.log(validate(8, 1)) //true
console.log(validate(0.08, 0.01)) //true
console.log(validate(0.008, 0.001)) //true
console.log(validate(0.016, 0.001)) //true
console.log(validate(0.08, 0.001)) //false


推荐阅读