确定浮点数中的前导零数

时间:2017-09-10 01:12:12

标签: javascript algorithm math floating-point language-agnostic

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

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

直观地说我假设有一个数学函数可以提供这个,或者至少是主要部分。但我既不记得也不知道哪一个。

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

在我的情况下,如果这是一个并发症,我不需要一些适用于负数的东西。

我想知道一般的做法是什么,不论语言如何。

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

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

4 个答案:

答案 0 :(得分:4)

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

  

x = [a 1 a 2 ... a n ] [0 1 0 <子> 2 ... 0 <子>米] [b <子> 1 b'的子> 2 。b <子>米

这意味着x的小数部分大于或等于10 -m ,并且小于10 -m + 1

换句话说,x的小数部分的十进制对数大于或等于–m,小于–m+1

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

&#13;
&#13;
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));
&#13;
&#13;
&#13;

  

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

以相同的方式,正整数x需要n个十进制数字来代表它,当且仅当n - 1 <= log10(x) < n时。

因此x的十进制表示中的位数为floor(log10(x)) + 1

那就是说,我不推荐使用这种方法来确定实际的位数。 log10不能保证给出对数的确切值(甚至不像IEEE 754允许的那样精确),这可能会导致某些边缘情况下的结果不正确。

答案 1 :(得分:2)

您可以使用简单的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);

答案 2 :(得分:1)

我的方法是使用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);
}

答案 3 :(得分:0)

您可以使用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);