确定浮点数中前导零的数量

Determine number of leading zeros in a floating point number

如何计算浮点数中小数点之后但第一个非零之前有多少个零。示例:

0 -> 0
1 -> 0
1.0 -> 0
1.1 -> 0
1.01 -> 1
1.00003456 ->4

凭直觉,我假设有一个数学函数可以提供这个功能,或者至少可以提供主要部分。但是想不起来也想不起来是哪一个

我知道可以通过先将数字转换为字符串来完成,只要数字不是科学计数法即可,但我想要一个纯数学解决方案。

在我的例子中,如果这很复杂,我不需要对负数有效的东西。

我想知道一般的方法是什么,不考虑语言。

但是如果有一个非常标准的数学函数,我也想知道JavaScript是否有这个函数。

旁注,我想知道这个计算是否与确定整数的十进制表示需要多少位的方法有关。

你可以用toFixed()方法来完成,但是我的代码只有一个缺陷,你需要指定点后面的数字的长度 . 这是因为该方法的使用方式。

注意:

toFixed() 方法的最大长度是 20,所以在 . 之后不要输入超过 20 个数字,如 in the docs

var num = 12.0003400;

var lengthAfterThePoint = 7;
var l = num.toFixed(lengthAfterThePoint);
var pointFound = false;
var totalZeros = 0;

for(var i = 0; i < l.length; i++){
  if(pointFound == false){
    if(l[i] == '.'){
      pointFound = true;
    }
  }else{
    if(l[i] != 0){
      break;
    }else{
      totalZeros++;
    }
  }
}
console.log(totalZeros);

补充答案

这是我的额外答案,在这个函数中,程序计算所有的零,直到最后一个非零。所以它忽略了最后的所有零。

var num = 12.034000005608000;

var lengthAfterThePoint = 15;
var l = num.toFixed(lengthAfterThePoint);
var pointFound = false;
var theArr = [];

for(var i = 0; i < l.length; i++){
  if(pointFound == false){
    if(l[i] == '.'){
      pointFound = true;
    }
  }else{
    theArr.push(l[i]);
  }
}


var firstNumFound = false;
var totalZeros = 0;

for(var j = 0; j < theArr.length; j++){
  if(firstNumFound == false){
    if(theArr[j] != 0){
      firstNumFound = true;
      totalZeros = totalZeros + j;
    }
  }else{
    if(theArr[j] == 0){
      totalZeros++;
    }
  }
}


var totalZerosLeft = 0;
for (var k = theArr.length; k > 0; k--) {
  if(theArr[k -1] == 0){
    totalZerosLeft++;
  }else{
    break;
  }
}

console.log(totalZeros - totalZerosLeft);

你可以用一个简单的 while 循环来完成:

function CountZeros(Num) {

    var Dec = Num % 1;
    var Counter = -1;

    while ((Dec < 1) && (Dec > 0)) {
        Dec = Dec * 10;
        Counter++;
    }
    Counter = Math.max(0, Counter); // In case there were no numbers at all after the decimal point.

    console.log("There is: " + Counter + " zeros");
}

然后把你要查询的号码传入函数即可:

CountZeros(1.0034);

x是一个非整数,可以写成整数部分的n位,然后是小数点,然后是m个零,然后是其余的小数部分。

x = [a1a2...an] . [0102...0m][b1b2...bm]

表示x的小数部分大于等于10–m,小于10–m+1

也就是说x的小数部分的十进制对数大于等于–m,小于–m+1.

这反过来意味着 x 的小数部分的十进制对数的整数部分等于 –m.

function numZeroesAfterPoint(x) {
  if (x % 1 == 0) {
    return 0;
  } else {
    return -1 - Math.floor(Math.log10(x % 1));
  }
}

console.log(numZeroesAfterPoint(0));
console.log(numZeroesAfterPoint(1));
console.log(numZeroesAfterPoint(1.0));
console.log(numZeroesAfterPoint(1.1));
console.log(numZeroesAfterPoint(1.01));
console.log(numZeroesAfterPoint(1.00003456));

As a sidenote, I wonder if this calculation is related to the method for determining how many digits are required for the decimal representation of an integer.

同理,一个正整数xn个十进制数字表示当且仅当n - 1 <= log10(x) < n

所以x的十进制表示的位数是floor(log10(x)) + 1.

也就是说,我不建议在实践中使用这种确定位数的方法。 log10 不保证给出准确的对数值(甚至不如 IEEE 754 允许的那样准确),这可能会在某些边缘情况下导致不正确的结果。

我的方法是使用 while() 循环比较 .floor(n) 值和它的 n.toFixed(x) 值,同时递增 x 直到两者不相等:

console.log(getZeros(0));           //0
console.log(getZeros(1));           //0
console.log(getZeros(1.0));         //0
console.log(getZeros(1.1));         //0
console.log(getZeros(1.01));        //1
console.log(getZeros(1.00003456));  //4

function getZeros(num) {
    var x = 0;
    if(num % 1 === 0) return x;
    while(Math.floor(num)==num.toFixed(x)) {x++;}
    return(x-1);
}