Priyanka
Priyanka

Reputation: 333

How to check if a floating point number is integer power of another number

function checkIfNumberIsPower(n,power) {
    if(n == 0) {
        return 0;
    }    
    var count = 0; 
    while(n != 1)
    { 
        console.log("hi")
        if(n % power != 0) {
           return false;
        }   
        n = n / power;   
        count++;  
    }
    console.log(count)
    return true;
}

var numb = 0.01;
var power = 10;
var numbCheck = checkIfNumberIsPower(numb,power);
console.log("numb is...."+numbCheck );

I am trying to check if number is power of 10. It works fine if numb is not a floating point number, but when I check a floating point number such as 0.01 it returns false (it should be true as 10^-2 = 0.01).

Upvotes: 3

Views: 171

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386680

For preventing the trap of precision of floating point arithmetic, you could store the direction of needed multiplication or division with the power and check if the value reaches one.

For preventing an infinity loop, another check is made by using the direction for a direction depending check and exit if the value goes into the unwanted direction. This result may be interpreted as well as not in power.

For all other values which are not zero, the value of power is returned.

function checkIfNumberIsPower(n, power) {
    var count = 0,
        direction = n < 1;

    if (!n) {
        return 'zero';
    }
    while (n !== 1) {
        if (direction) {
            n *= power;
            count--;
        } else {
            n /= power;
            count++;
        }
        if (direction ? n > 1 : n < 1) {
            return 'missing precision or not power';
        }
    }
    return count;
}

console.log(checkIfNumberIsPower(0.01, 10));
console.log(checkIfNumberIsPower(1000, 10));
console.log(checkIfNumberIsPower(1001, 10));

console.log(checkIfNumberIsPower(8, 2));
console.log(checkIfNumberIsPower(0.125, 2));

console.log(checkIfNumberIsPower(4, 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 4

kfx
kfx

Reputation: 8537

It's easy to do this check for integer numbers. So, in order to check it for floating point number we can invert the number, and then call the check for integer numbers. This might still lead to wrong results for some floating point values due to the limited precision, but works for as long as not too many digits are required.

function checkIfNumberIsPowerInt(n, power) {
    var count = 0;
    while(n != 1)
    { 
        if(n % power != 0) {
           return false;
        }   
        n /= power;   
        count++;  
    }
    return true;
}

function checkIfNumberIsPower(n, power) {
    if(n === 1) { // for all x, x^0 = 1
        return true;
    }
    if(!n) { // for no x, x^y = 0
        return false;
    }
    if(Math.abs(n) > 0 && Math.abs(n) < 1) {
        return checkIfNumberIsPowerInt(1 / n, power);
    }
    return checkIfNumberIsPowerInt(n, power);
}


console.log(checkIfNumberIsPower(0.01, 10));    // 10^-2 = 0.01
console.log(checkIfNumberIsPower(0.01, -10));   // -10^-2 = 0.01
console.log(checkIfNumberIsPower(-0.1, -10));   // -10^-1 = -0.1
console.log(checkIfNumberIsPower(-0.01, -10));  // -10^-2 =/= -0.01

Upvotes: 2

Related Questions