将带分数(如“99 5/32”)转换为浮点值

问题描述 投票:0回答:4

数据以字符串形式到达

'99 10/32'
'99 5/32'
'100 5/32'
'100 25/32'

我需要十进制形式,所以我已经这样做了,但结果并不总是正确的:

...
    $priceRaw = '99 5/32'; // ******also could be $priceRaw = 100 15/32, etc
    $priceFrac = (str_replace("/32","",substr($priceRaw, -5))/100);
    $priceFirst = (substr($priceRaw, 0, 3)*1);
    $value = $priceFirst+$priceFrac;
// original code that failed with one digit, e.g. 5/32
// $value=str_replace("/32.","",str_replace(" ",".0",$e->plaintext));
...
php string formatting numeric text-parsing
4个回答
1
投票

按空格分割字符串以获得部分

list($priceFirst, $priceFrac) = explode(' ', $priceRaw); 
$priceFrac = (str_replace("/32","",$priceFrac)/100);
echo $value = $priceFirst+$priceFrac;

1
投票

我会因为

eval
而受到打击,但适用于所有分数。

分割空间并在计算中使用数字:

$priceRaw = '99 5/32';
list($num, $frac) = explode(' ', $priceRaw);
eval("\$result = $num + $frac;");
echo $result; // 99.15625

或将空格替换为

+
并计算:

$calc = str_replace(' ', '+', $priceRaw);
eval("\$result = $calc;");
echo $result; // 99.15625

然后只需

round
number_format
或任何您需要的内容。我可能错过了一些重要的东西,因为你的数学很有趣。


0
投票

或者我们可以走正则表达式路线:

function convFrac($in) {
    if( preg_match('#^(\d+)\s+(\d+)/(\d+)$#', $in, $match) ) {
        $tmp = array_map('intval', array_slice($match, 1));
        return $tmp[0] + $tmp[1] / $tmp[2];
    }
    throw new \Exception("Badly formatted fraction.");
}

var_dump( convFrac('99 5/32') ); // float(99.15625)

0
投票

您可以使用“立即调用函数表达式”将格式化字符串解析为其单独的整数部分,然后执行所需的数学运算。如果还有其他方法,我不建议eval()。我的片段在构建时考虑到了灵活性,因此

32
不是一个硬编码/魔术数字。分子甚至可以大于分母,结果仍然是正确的。如果输入字符串中的任何数字可能是浮点值,请使用
%f
而不是
%d
代码:(

演示

$tests = [ '99 10/32', '99 5/32', '100 5/32', '100 25/32', '4 20/5', ]; foreach ($tests as $priceRaw) { echo (fn($i, $n, $d) => $i + $n / $d)(...sscanf($priceRaw, '%d %d/%d')) . "\n"; }

输出:

99.3125 99.15625 100.15625 100.78125 8

IIFE 可以作为变量分离出来,具有相同的效果。

$func = fn($i, $n, $d) => $i + $n / $d; foreach ($tests as $priceRaw) { echo $func(...sscanf($priceRaw, '%d %d/%d')) . "\n"; }

或更老套/冗长:

function doMath($i, $n, $d) { return $i + $n / $d; } foreach ($tests as $priceRaw) { echo doMath(...sscanf($priceRaw, '%d %d/%d')) . "\n"; }

© www.soinside.com 2019 - 2024. All rights reserved.