SO,
The problem
My question is about trivial thing: how to convert numeric string to it's plain ("native") representation. That means: if numeric string is already in plain view, leave it as it is, but if it is in scientific notation, convert it. Sample:
"3" --> "3" "1.5" --> "1.5" "-15.482E-2" --> "-0.15482"
Numeric string supposed to be valid, and if it's not - then it's not a case for conversion (we're free to return null or empty string, for example).
Use-case
That is needed for bcmath
because it can't work with scientific floats. Thus, they need to be converted to plain strings (asked here). So important consequence from this use-case is that numeric string can be something like 1E-300
or 1E+500
. Since we're working with bcmath
- it's intention is to handle such things.
My approach
For now, I've implemented that with regex-almighty, like:
function parseFloat($string)
{
$string = (string)$string;
if(preg_match('/^[+-]?(\d+|\d+\.\d*)[Ee]([+-]?)(\d+)$/', $string, $matches))
{
$precision = false!==($dot=strpos($matches[1], '.'))
?strlen($matches[1])-$dot-1
:0;
$precision = $matches[2]=='-'
?$precision + (int)$matches[3]
:$precision - (int)$matches[3];
return number_format($string, $precision<0?0:$precision, '', '');
}
if(preg_match('/^[+-]?(\d+|\d+\.\d+)$/', $string))
{
return $string;
}
}
The question
I feel that there should be more simple and wise way to do that. How to achieve that in more simple way in PHP? May be some tricky sprintf()
format?
Important note: I don't want to deal with precision. I want black box. Pass something numeric there - got string as output. That's all. Don't want to deal with anything else. In fact, all my regex are about calculating length & precision - so, sure, if pass them explicitly (as parameters, for example) - we cat get rid of regex. But - no, that's not what I want.
echo sprintf("%s", (float)"-15.482E-5");
?? just for fun – Currant"1E-8"
– Silurianbc
) to my non-regex solution - so it definitely is good. I'll wait for other opinions, however – Silurian