Converting a number with comma as decimal point to float

PhpParsingFloating Point

Php Problem Overview


I have a list of prices with a comma for a decimal point and a dot as the thousand separator.

Some examples:

12,30
116,10
1.563,14

These come in this format from a third party. I want to convert them to floats and add them together.

What is the best way to do this? number_format doesn't seem to work with this format, and str_replace seems like overkill, as I have to do it more that once on each number.

Is there are better way? Thanks.

Php Solutions


Solution 1 - Php

Using str_replace() to remove the dots is not overkill.

$string_number = '1.512.523,55';
// NOTE: You don't really have to use floatval() here, it's just to prove that it's a legitimate float value.
$number = floatval(str_replace(',', '.', str_replace('.', '', $string_number)));




// At this point, $number is a "natural" float.
print $number;

// At this point, $number is a "natural" float. print $number;

This is almost certainly the least CPU-intensive way you can do this, and odds are that even if you use some fancy function to do it, that this is what it does under the hood.

Solution 2 - Php

This function is compatible for numbers with dots or commas as decimals

function floatvalue($val){
            $val = str_replace(",",".",$val);
            $val = preg_replace('/\.(?=.*\.)/', '', $val);
            return floatval($val);
}

This works for all kind of inputs (American or european style)

echo floatvalue('1.325.125,54'); // The output is 1325125.54
echo floatvalue('1,325,125.54'); // The output is 1325125.54
echo floatvalue('59,95');        // The output is 59.95
echo floatvalue('12.000,30');    // The output is 12000.30
echo floatvalue('12,000.30');    // The output is 12000.30

Solution 3 - Php

If you're using PHP5.3 or above, you can use numfmt_parse to do "a reversed number_format". If you're not, you stuck with replacing the occurrances with preg_replace/str_replace.

Solution 4 - Php

You could use the NumberFormatter class with its parse method.

Solution 5 - Php

Might look excessive but will convert any given format no mater the locale:

function normalizeDecimal($val, int $precision = 4): string
{
    $input = str_replace(' ', '', $val);
    $number = str_replace(',', '.', $input);
    if (strpos($number, '.')) {
        $groups = explode('.', str_replace(',', '.', $number));
        $lastGroup = array_pop($groups);
        $number = implode('', $groups) . '.' . $lastGroup;
    }
    return bcadd($number, 0, $precision);
}

Output:

.12           -> 0.1200
123           -> 123.0000
123.91        -> 12345678.9100
123 456 78.91 -> 12345678.9100
123,456,78.91 -> 12345678.9100
123.456.78,91 -> 12345678.9100
123 456 78,91 -> 12345678.9100

Solution 6 - Php

Assuming they are in a file or array just do the replace as a batch (i.e. on all at once):

$input = str_replace(array('.', ','), array('', '.'), $input); 

and then process the numbers from there taking full advantage of PHP's loosely typed nature.

Solution 7 - Php

from PHP manual:

> str_replace — Replace all occurrences > of the search string with the > replacement string

I would go down that route, and then convert from string to float - floatval

Solution 8 - Php

You could use filter_var.

$floatNumber = (float) filter_var($string, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

Solution 9 - Php

For those who want an example of NumberFormatter :

	$test='2,345.67';

//	OOP Version
	$numberFormatter=new NumberFormatter('en-AU',NumberFormatter::DECIMAL);
	$number=$numberFormatter->parse($test);
	print $number;

//	Procedural Version
	$numberFormatter=numfmt_create('en_AU',NumberFormatter::DECIMAL);
	$number=numfmt_parse($numberFormatter,$test);
	print $number;

Of course your locale may very.

Not sure why anyone would opt for the procedural version.

Note that one major difference between NumberFormat and the str_replace type solutions is that NumberFormatter is sensitive to where you put your thousands and decimal characters; using 1,2345.00 won’t work.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAineView Question on Stackoverflow
Solution 1 - PhpTeekinView Answer on Stackoverflow
Solution 2 - PhpRaimonView Answer on Stackoverflow
Solution 3 - PhpBjörnView Answer on Stackoverflow
Solution 4 - PhpGumboView Answer on Stackoverflow
Solution 5 - PhpAdrian PiechotaView Answer on Stackoverflow
Solution 6 - PhpPaul NormanView Answer on Stackoverflow
Solution 7 - PhpYishai LandauView Answer on Stackoverflow
Solution 8 - PhpKristaps J.View Answer on Stackoverflow
Solution 9 - PhpManngoView Answer on Stackoverflow