简体   繁体   中英

Determine number of leading zeros in a floating point number

How can I calculate how many zeros come after the decimal point but before the first non-zero in a floating point number. Examples:

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

Intuitively I assume there is a math function that provides this, or at least does the main part. But I can neither recall nor figure out which one.

I know it can be done by first converting the number to a string, as long as the number isn't in scientific notation, but I want a pure math solution.

In my case I don't need something that works for negative numbers if that's a complication.

I'd like to know what the general ways to do it are, irrespective of language.

But if there is a pretty standard math function for this, I would also like to know if JavaScript has this function.

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.

Let x be a non-whole number that can be written as n digits of the whole part, then the decimal point, then m zeroes, then the rest of the fractional part.

x = [a 1 a 2 ...a n ] . [0 1 0 2 ...0 m ][b 1 b 2 ...b m ]

This means that the fractional part of x is larger than or equal to 10 –m , and smaller than 10 –m+1 .

In other words, the decimal logarithm of the fractional part of x is larger than or equal to –m , and smaller than –m+1 .

Which, in turn, means that the whole part of the decimal logarithm of the fractional part of x equals –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.

In the same manner, a positive integer x takes n decimal digits to represent it if and only if n - 1 <= log10(x) < n .

So the number of digits in the decimal representation of x is floor(log10(x)) + 1 .

That said, I wouldn't recommend using this method of determining the number of digits in practice. log10 is not guaranteed to give the exact value of the logarithm (not even as exact as IEEE 754 permits), which may lead to incorrect results in some edge cases.

You can do it with a simple while loop:

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");
}

Then just pass the number you want to check into the function:

CountZeros(1.0034);

My approach is using a while() loop that compares the .floor(n) value with the n.toFixed(x) value of it while incrementing x until the two are not equal:

 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); } 

You can do it with toFixed() method, but there is only one flaw in my code, you need to specify the length of the numbers that comes after the point . It is because of the way the method is used.

NOTE:

The max length for toFixed() method is 20, so don't enter more than 20 numbers after . as said 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);

Extra Answer

This is my extra answer, in this function, the program counts all the zeros until the last non-zero . So it ignores all the zeros at the end.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM