在PHP中将混合分数字符串转换为浮点数

4
我假设在PHP中有一种简单的方法可以将像18 5/16这样的字符串转换为浮点数18.3125。我找不到一个直接的函数来完成它。是否存在这样的函数,还是我需要自己编写代码?
2个回答

7

我认为这样的功能不存在,至少不是与PHP捆绑在一起的。

如果您的字符串始终具有相同的格式,编写执行此操作的函数应该不会太难;例如,我认为以下内容应该可以解决问题:

$str = '18 5/16';
var_dump(calc($str));

function calc($str) {
    $int = 0;
    $float = 0;
    $parts = explode(' ', $str);
    if (count($parts) >= 1) {
        $int = $parts[0];
    }
    if (count($parts) >= 2) {
        $float_str = $parts[1];
        list($top, $bottom) = explode('/', $float_str);
        $float = $top / $bottom;
    }
    return $int + $float;
}

这将为您提供以下输出结果:
float 18.3125


你可以利用几个正则表达式来缩短一些内容;我想下面的例子应该可以解决问题:

function calc($str) {
    if (preg_match('#(\d+)\s+(\d+)/(\d+)#', $str, $m)) {
        return $m[1] + $m[2] / $m[3];
    }
    return 0;
}



如果PHP中没有捆绑,但已经存在,也许这个类可以帮助:Eval Math

免责声明:我没有测试过它,所以不确定它是否适用于您的特定情况。


1
我喜欢更短的版本,但最好用 ^$ 括起来正则表达式。 - aaz

4
为了扩展Pascal的例子,下面是一个更加健壮的解决方案,可以处理大于1和小于1的分数。
function parseFraction(string $fraction): float 
{
  if(preg_match('#(\d+)\s+(\d+)/(\d+)#', $fraction, $m)) {
    return ($m[1] + $m[2] / $m[3]);
  } else if( preg_match('#(\d+)/(\d+)#', $fraction, $m) ) {
    return ($m[1] / $m[2]);
  }
  return (float)0;
}

这里有一些基本的测试覆盖率,对于将此代码与phpunit集成非常有用

class FractionParserTest extends TestCase
{
  /**
   * < 1
   * @return void
   */
  public function testSimple(): void
  {
    $qty = '3/4';
    $res = parseFraction($qty);
    $this->assertEquals(0.75, $res);
  }

  /**
   * > 1
   * @return void
   */
  public function testComplex(): void
  {
    $qty = '18 5/16';
    $res = parseFraction($qty);
    $this->assertEquals(18.3125, $res);
  }
}

我印象深刻。虽然我现在没有紧急需求,但我可能还是会去看看它。它看起来很酷。 - TRiG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接