Implementing thousands (k, kk) interpreter

Viewed 114

Problem

I'm trying to create a tool that takes a number as input, for example - 1kk, and replaces each k with multiplication by 1000, i.e. here we get 1000000.

There's no problem when dealing with integers, but I'm struggling to implement and algorithm which will replace numbers with floating point like 12.345kk with 12345000.


Possible solution

Okay, I could replace each k with multiplication by 1000 and then eval the whole expression:

$inp= "12.345kk";
$number = preg_replace('/[kt]/','*1000',$inp);
eval("\$result = {$number};");
echo($result); // 12345000

but it's really dangerous since the tool takes user input, and user can write anything they want.

Could you provide a safe solution to this problem?

It's a PHP question, but I guess the solution should be more-or-less similar in other languages, an algorithm itself shouldn't be very difficult.

3 Answers

You could use preg_match to split the input into digits and multipliers and multiply the digits by 1000 to the length of the multiplier string:

$inp= "12.345kk";
$number = 0;
if (preg_match('/^([\d.]+)([kt]+)/', $inp, $matches)) {
    $number = $matches[1];
    $multipliers = $matches[2];
    $number *= 1000 ** strlen($multipliers);
}
echo $number;

Output:

12345000

Demo on 3v4l.org

If you are sure about format of your number you can count k chars in your string, then cast it to number and multiply by proper power.

$inp= "12.345kk";

$count = substr_count($inp,'k');

$number = (double)$inp*1000**$count;

print($number);

You're concerns are warranted, you should never run user input through eval(), unless you absolutely have to. You don't have to do that here. Let me show you one possible solution.

You can get the numeric part of the input by casting it to float. You can get the number of k characters by using substr_count(). You can then calculate the resulting number by using the number of ks as exponent for the number 1000 and multiply that with the input number:

$inp = "12.345kk";

$number = (float) $inp;                        // 12.345
$factor = pow(1000, substr_count($inp, 'k'));  // 1000^2

$result = $number * $factor;                   // 12345000

Note that you could also use the ** operator instead of pow. However, I'd argue that pow will be easily understood by programmers unfamiliar with PHP and is therefore preferable.

Related