• 首页
• PHP
• 将浮点数转换为纯字符串表示

# 将浮点数转换为纯字符串表示 [英] Convert float to plain string representation

### 问题描述

<上一页>"3" --> "3""1.5" --> "1.5"-15.482E-2" --> -0.15482"

``函数 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)){返回\$字符串；}}``

``函数 convertFloat(\$floatAsString){\$norm = strval(floatval(\$floatAsString));if ((\$e = strrchr(\$norm, 'E')) === false) {返回\$标准；}返回 number_format(\$norm, -intval(substr(\$e, 1)));}``

``3 31.5 1.5-15.482e-2 -0.154821e-8 0.000000011e+3 1000-4.66E-2 -0.04663e-3 0.003``

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 , 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.

Because `sprintf()` with `"%.f"` has trouble with expressions such as `"1e-8"`, some text processing may be required:

``````function convertFloat(\$floatAsString)
{
\$norm = strval(floatval(\$floatAsString));

if ((\$e = strrchr(\$norm, 'E')) === false) {
return \$norm;
}

return number_format(\$norm, -intval(substr(\$e, 1)));
}
``````

Tested with:

``````3          3
1.5        1.5
-15.482e-2 -0.15482
1e-8       0.00000001
1e+3       1000
-4.66E-2   -0.0466
3e-3       0.003
``````