Question

let's say I have a variable containing an integer or a float (since integers might overflow into a float in PHP).

I want to run some operation to get the leftmost digit and the rest of the remaining digits.

To explain better:

<?php

$x   = NULL;  //this will hold first digit
$num = 12345; //int

/// run operation


//outputs
//$x   = 1;
//$num = 2345;
var_dump($x, $num);

?>

Now, I know there's multitudes of ways to do this if you represent the number as a string, but I'm trying to avoid type casting it into a string.

I'm probably looking for a solution which includes bitwise operations, but I'm pretty weak in that topic so I'm hoping someone who usually works low-level might be able to answer this!

Thanks a bunch.

Was it helpful?

Solution

Avoids using any string manipulation, but no guarantees for float or even negative values

$x   = NULL;  //this will hold first digit
$num = 12345; //int

$m = 1;
while(true) {
    $m *= 10;
    if ($m > $num)
        break;
}

$m /= 10;

$x = (int) floor($num / $m);
$num = $num % $m;


//outputs
//$x   = 1;
//$num = 2345;
var_dump($x, $num);

OTHER TIPS

I'm sure there is a way to do this without casting it to a string, but why? The string detour is so easy:

$x = (int)substr($num, 0, 1); 

It'll give you a nice, proper integer.

Obviously, this does no extended checking for faulty input, and requires $num to be a valid number.

Math-only method:

function leftMost($num) {  
    return floor($num/pow(10,(floor((log10($num))))));
}

explained I guess...

1+ log10 of num calculates the number of digits a number is, we floor it to remove any decimal values, put it as the exponent so for a 1 digit number we get 10^0=1, or a 8 digit number we get 10^8. We then are just divding 12345678/10000000 = 1.2345678, which gets floor'd and is just 1.

note: this works for numbers between zero and one also, where it will return the 2 in 0.02, and a string transform will fail.

If you want to work with negative numbers, make $num = abs($num) first.

To get the rest of the digits

$remainingnum = (int)substr((string)$num, 1, strlen($num));

If you typcast the value to a string you can use the array type selector.

For example:

$n = (string)12345676543.876543;
echo (int)$n[0];

@Mark Baker offered the best solution, though you should do abs(floor($num)) before applying the algorithm.

I know you stated you wanted to avoid casting to a string, but if you want to loop over the digits in PHP, this will be the fastest way:

$len = strlen($n);
for ($i = 0; $i < $len; ++$i)
  $d = $n[$i];

In a quick-and-dirty benchmark, it was around 50% faster than the equivalent set of mathematical expressions, even when minimizing the calls to log and exp.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top