简体   繁体   中英

Javascript to PHP function not returning the same results

I have two function here written in javascript that increments/decrements numbers. I need to have those functions written in PHP (and I am not good at PHP at all). The problem I have is that in PHP all the values returned by the functions inc() and dec() are 0.

Here is the JS:

function getInc(num) {
    let abs = Math.abs(num);
    if ((Math.log10(abs) % 1 === 0) && (num < 0)) return num / 10;
    let inc = Math.pow(10, Math.floor(Math.log10(abs)));
    if (abs === num) return inc;
    return -inc;
}
function inc(num) {
    if ((num === 0) || (typeof num != 'number')) { return 0 }
    if ((num < -1) && (num >= -10)) {
        return Math.floor(Math.round(num) - getInc(num))
    }
    if ((num < 0) && (num >= -1)) {
        const result = num - getInc(num);
        return Math.floor(parseFloat(result / getInc(num)).toPrecision(12)) * getInc(num)
    }
    if (num >= 1 && num < 10) {
        return Math.round(Math.floor(num + getInc(num)));
    }
    if ((num >= 10) || (num > 0 && num < 1)) {
        const result = Math.ceil(num / getInc(num)) * getInc(num);
        if (result === num) { return num + getInc(num) }
        else { return result }
    }
    if (num <= -20) {
        const result = -Math.ceil(num / -getInc(num)) * getInc(num) - getInc(num);
        if (result === num) { return num + getInc(num) }
        else { return result }
    }
    if (num < -10 && num > -20) {
        return -9
    }
}

function getDec(num) {
    let abs = Math.abs(num);
    if ((Math.log10(abs) % 1 === 0) && (num > 0)) return num / 10;
    let inc = Math.pow(10, Math.floor(Math.log10(abs)));
    if (abs === num) return inc;
    return -inc;
}

function dec(num) {
    if ((num === 0) || (typeof num != 'number')) { return 0 }
    if ((num < -1) && (num > -10)) {
    }
    if ((num < 0) && (num >= -1)) {
        const result = num + getDec(num);
        return Math.floor(parseFloat(result / getDec(num)).toPrecision(12)) * getDec(num)
    }
    if (num > 1 && num < 10) {
        return Math.round(Math.floor(num - getDec(num)));
    }
    if ((num >= 20) || (num > 0 && num <= 1)) {
        const result = Math.floor(parseFloat(num / getDec(num)).toPrecision(12)) * getDec(num) - getDec(num);
        if (result === num) { return num - getDec(num) }
        else { return result }
    }
    if (num >= 10 && num < 20) {
        return 9
    }
    if (num <= -10) {
        const result = -(Math.ceil(num / -getDec(num)) * getDec(num) - getDec(num));
        if (result === num) { return num - getDec(num) }
        else { return result }
    }
}

And here is the PHP:

<?php
function getInc( $num ) {
    $abs = abs( $num );
    if ( ( log10( $abs ) % 1 === 0 ) && ( $num < 0 ) ) { return $num / 10;  }
    $inc = pow( 10, floor( log10( $abs ) ) );
    if ( $abs === $num ) { return $inc;  }
    return -$inc;
}
function inc( $num ) {
    if ( ( $num === 0 ) || ( gettype( $num ) != 'number' ) ) { return 0;  }
    if ( ( $num < -1 ) && ( $num >= -10 ) ) {
        return floor( round( $num ) - getInc( $num ) );
    }
    if ( ( $num < 0 ) && ( $num >= -1 ) ) {
        $result = $num - getInc( $num );
        return floor( floatval( $result / getInc( $num ) )->toPrecision( 12 ) ) * getInc( $num );
    }
    if ( $num >= 1 && $num < 10 ) {
        return round( floor( $num + getInc( $num ) ) );
    }
    if ( ( $num >= 10 ) || ( $num > 0 && $num < 1 ) ) {
        $result = ceil( $num / getInc( $num ) ) * getInc( $num );
        if ( $result === $num ) { return $num + getInc( $num );  } else {
            return $result;
        }
    }
    if ( $num <= -20 ) {
        $result = -ceil( $num / -getInc( $num ) ) * getInc( $num ) - getInc( $num );
        if ( $result === $num ) { return $num + getInc( $num );  } else {
            return $result;
        }
    }
    if ( $num < -10 && $num > -20 ) {
        return -9;
    }
}

function getDec( $num ) {
    $abs = abs( $num );
    if ( ( log10( $abs ) % 1 === 0 ) && ( $num > 0 ) ) { return $num / 10;  }
    $inc = pow( 10, floor( log10( $abs ) ) );
    if ( $abs === $num ) { return $inc;  }
    return -$inc;
}

function dec( $num ) {
    if ( ( $num === 0 ) || ( gettype( $num ) != 'number' ) ) { return 0;  }
    if ( ( $num < -1 ) && ( $num > -10 ) ) {
    }
    if ( ( $num < 0 ) && ( $num >= -1 ) ) {
        $result = $num + getDec( $num );
        return floor( $result / getDec( $num ) ) * getDec( $num );
    }
    if ( $num > 1 && $num < 10 ) {
        return round( floor( $num - getDec( $num ) ) );
    }
    if ( ( $num >= 20 ) || ( $num > 0 && $num <= 1 ) ) {
        $result = floor($num / getDec( $num ) ) * getDec( $num ) - getDec( $num );
        if ( $result === $num ) { return $num - getDec( $num );  } else {
            return $result;
        }
    }
    if ( $num >= 10 && $num < 20 ) {
        return 9;
    }
    if ( $num <= -10 ) {
        $result = -( ceil( $num / -getDec( $num ) ) * getDec( $num ) - getDec( $num ) );
        if ( $result === $num ) { return $num - getDec( $num );  } else {
            return $result;
        }
    }
}

Do you see where is this issue coming from? Thank you in advance

Edited PHP:

<?php
function getInc($num) {
    $abs = abs($num);
    $inc = pow(10, floor(log10($abs)));
    if ($abs === $num) { return $inc;  }
    return -$inc;
}
function inc($num) {
    if (($num === 0) || !is_numeric($num) || is_string($num)) { return 0;  }
    if (($num < -1) && ($num >= -10)) {
        return round(round($num) - getInc($num));
    }
    if (($num < 0) && ($num >= -1)) {
        $result = $num - getInc($num);
        return round(floatval($result / getInc($num))) * getInc($num);
    }
    if ($num >= 1 && $num < 10) {
        return round(round($num + getInc($num)));
    }
    if (($num >= 10) || ($num > 0 && $num < 1)) {
        $result = ceil($num / getInc($num)) * getInc($num);
        if ($result === $num) { return $num + getInc($num);  } else {
            return $result;
        }
    }
    if ($num <= -20) {
        $result = -ceil($num / -getInc($num)) * getInc($num) - getInc($num);
        if ($result === $num) { return $num + getInc($num);  } else {
            return $result;
        }
    }
    if ($num < -10 && $num > -20) {
        return -9;
    }
}

function getDec($num) {
    $abs = abs($num);
    $inc = pow(10, floor(log10($abs)));
    if ($abs === $num) { return $inc;  }
    return -$inc;
}

function dec($num) {
    if (($num === 0) || !is_numeric($num) || is_string($num)) { return 0; }
    if (($num < -1) && ($num > -10)) {
    }
    if (($num < 0) && ($num >= -1)) {
        $result = $num + getDec($num);
        return round($result / getDec($num)) * getDec($num);
    }
    if ($num > 1 && $num < 10) {
        return round(round($num - getDec($num)));
    }
    if (($num >= 20) || ($num > 0 && $num <= 1)) {
        $result = round($num / getDec($num)) * getDec($num) - getDec($num);
        if ($result === $num) { return $num - getDec($num);  } else {
            return $result;
        }
    }
    if ($num >= 10 && $num < 20) {
        return 9;
    }
    if ($num <= -10) {
        $result = -(ceil($num / -getDec($num)) * getDec($num) - getDec($num));
        if ($result === $num) { return $num - getDec($num);  } else {
            return $result;
        }
    }
}


?>

gettype returns integer or double for numbers.

To test a numeric variable, you can use is_numeric($num) .

To filter numeric string, you can use is_numeric($num) && is_string($num) .

One error I see is that inside of inc() you are trying to call a class method on a float here:

    return floor(floatval($result / getInc($num))->toPrecision(12)) * getInc($num);

floor() returns a float (even though it's rounded down to the lowest integer number) as described in the manual . You can't call a function/method on a float in PHP as you can in JavaScript.

You can try to use round() like this instead:

    return round(floatval($result / getInc($num)),12) * getInc($num);

As for why inc() and dec() are returning 0, the first line of both functions check for number by doing this:

  if (($num === 0) || (gettype($num) != 'number')) {

gettype() doesn't return a type of 'number'. In JavaScript integers and floats are all considered of type number but in PHP they are separate. You can use 'is_numeric()` instead.

  if (($num === 0) || !is_numeric($num)) {

That will check for strings that look like numbers as well so if you don't want numeric strings, you can do another check to filter those out. You could use is_string() for that.

  if (($num === 0) || !is_numeric($num) || is_string($num)) {

----------Edited after getting some test numbers in comment----------

Ok, I think I found another type checking error. The following line returns false because you are checking a float against an int:

    $result = ceil($num / getInc($num)) * getInc($num);
    if ($result === $num) {

$result is a always a float because ceil() returns a result of type float. When you do the strict comparison === and $num happens to be an integer, it returns false because even though they might be the same value, they are not identical types. That causes the integer input of 10 to act strangely.

(10 === 10.0) // false in php because int !== float

However if youuse the equals comparison instead == it will probably come out ok. I wouldn't be surprised if there are some other type checking errors, I just didn't go through each function.

It seems like the big difference you are running up against is because of the variable types in JavaScript are different from the variable types in PHP. JavaScript only has the notion of type number which are all stored as floating point numbers but it doesn't distinguish between integers and floats. However PHP has both floats and integers . When you do strict comparison, you need to make sure not only the value is equal but the type is too.

Hope this helps you work through any other bugs in the code.

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