简体   繁体   English

PHP中小数和分数之间的转换

[英]How to convert between decimals and fractions in PHP

I am trying to multiply numbers by 2 and these numbers are either whole numbers or fractions.我试图将数字乘以 2,这些数字要么是整数,要么是分数。 I am pulling in these numbers dynamically through ACF fields on WordPress as text field.我通过 WordPress 上的 ACF 字段作为文本字段动态提取这些数字。 But some of these dynamic numbers are not fractions and just whole numbers such as 3 or 1. What I am trying to do is double the number so 3/4 would be 1 1/2.但其中一些动态数字不是分数,而是整数,例如 3 或 1。我想要做的是将数字翻倍,因此 3/4 将是 1 1/2。 But when I multiply the fraction such as 3/4, it turns into 1.5.但是当我乘以 3/4 等分数时,它变成了 1.5。 I used fubars code to get these numbers to stay as fractions but then I run into the issue of proper fractions showing up as decimals.我使用fubars代码让这些数字保持为分数,但后来我遇到了正确分数显示为小数的问题。

When you click 6 in the serving size, it should double the recipe as fractions.当您在份量中单击 6 时,它应该将配方作为分数加倍。

Here is a code snippet from my template taking care of these numbers (I have javascript just hiding/showing the number on click depending on the serving size):这是我的模板中处理这些数字的代码片段(我有 javascript 只是根据服务大小隐藏/显示点击数字):

<?php 
$number = get_sub_field('number'); // some numbers are 1/2 and 3/4 and some are 1 or 3
$double = 2;
$result = $number * $double;
?> 
<?php echo $result; ?>

Would it be best for these to have a value as decimals but somehow use jQuery/javascript to convert it to fractions for front-end only?最好将这些值设为小数,但以某种方式使用 jQuery/javascript 将其转换为仅用于前端的分数?

Thoughts?想法? I would really appreciate it!我真的很感激!

Let me know.让我知道。

Thanks!谢谢!

EDIT编辑

For those working with ACF fields via WordPress, heres a simple solution for this.对于那些通过 WordPress 使用 ACF 字段的人,这里有一个简单的解决方案。 The $number field is a number ACF field, so working with decimals to begin with. $number 字段是一个数字 ACF 字段,因此首先使用小数。

<!-- Create the function -->
function convert($number) {
<!-- pull in the number field and multiply it by 2 (since we are 
doubling -->
    $number = $number * 2;
<!-- Create and Array of all the possibilities of fractions (this 
instance is cooking measurements -->
    $fractions = array(
                    0625    => '1/16',
                    1875    => '3/16',
                    3125    => '5/16',
                    4375    => '7/16',
                    5625    => '9/16',
                    6575    => '11/16',
                    8125    => '13/16',
                    875     => '14/16',
                    9375    => '15/16',
                    125     => '1/8',
                    33      => '1/3',
                    25      => '1/4',
                    66      => '2/3',
                    5       => '1/2',
                    375     => '3/8',
                    625     => '5/8',
                    75      => '3/4'
                );
    <!-- explode the part after the decimal point and convert it to the 
    fraction above -->
    $parts = explode('.', $number);
    if(isset($parts[1])) {
        echo $parts[0].' '.$fractions[$parts[1]];
    } else {
    echo $number;
}
}

Then just add convert() around the $number value that is being pulled onto the WP template so convert($number).然后只需在被拉到 WP 模板上的 $number 值周围添加 convert(),这样 convert($number)。

When your number field contains a fractional value, PHP will actually consider it to be a string , not a number , and it'll therefore need to be converted to a number before you can use it to perform arithmetic.当您的数字字段包含小数值时,PHP 实际上会将其视为string ,而不是number ,因此需要先将其转换为number然后才能使用它执行算术运算。

Since you've updated the requirements of your question, I've modified my answer to include two functions.由于您更新了问题的要求,因此我修改了答案以包含两个功能。 I've written one function to convert from a fractional to decimal value, and another to convert from a decimal to a fractional value.我编写了一个函数来将小数转换为十进制值,另一个函数将小数转换为小数。

You can see a working example of this here: https://3v4l.org/ft0ZT你可以在这里看到一个工作示例: https : //3v4l.org/ft0ZT

<?php

function fractionToDecimal($fraction) 
{
    // Split fraction into whole number and fraction components
    preg_match('/^(?P<whole>\d+)?\s?((?P<numerator>\d+)\/(?P<denominator>\d+))?$/', $fraction, $components);

    // Extract whole number, numerator, and denominator components
    $whole = $components['whole'] ?: 0;
    $numerator = $components['numerator'] ?: 0;
    $denominator = $components['denominator'] ?: 0;

    // Create decimal value
    $decimal = $whole;
    $numerator && $denominator && $decimal += ($numerator/$denominator);

    return $decimal;
}

function decimalToFraction($decimal) 
{
    // Determine decimal precision and extrapolate multiplier required to convert to integer
    $precision = strpos(strrev($decimal), '.') ?: 0;
    $multiplier = pow(10, $precision);

    // Calculate initial numerator and denominator
    $numerator = $decimal * $multiplier;
    $denominator = 1 * $multiplier;

    // Extract whole number from numerator
    $whole = floor($numerator / $denominator);
    $numerator = $numerator % $denominator;

    // Find greatest common divisor between numerator and denominator and reduce accordingly
    $factor = gmp_intval(gmp_gcd($numerator, $denominator));
    $numerator /= $factor;
    $denominator /= $factor;

    // Create fraction value
    $fraction = [];
    $whole && $fraction[] = $whole;
    $numerator && $fraction[] = "{$numerator}/{$denominator}";

    return implode(' ', $fraction);
}

// Examples
var_dump(fractionToDecimal('1/25'));   // 0.04
var_dump(fractionToDecimal('2 3/4'));  // 2.75
var_dump(fractionToDecimal('6/4'));    // 1.5

var_dump(decimalToFraction(1.375));    // 1 3/8
var_dump(decimalToFraction(3));        // 3
var_dump(decimalToFraction(2.875));    // 2 7/8

You are not multiplying exactly 100 with 0.1, but with with 0.09999999998 ... And when it comes to ( int ), it converts numbers like 4.999 to 4 , so your result 1020636.999999999 becomes 1020636 when counting with ( int ).你是不是恰好0.1乘以100,但与0.09999999998 ...当它涉及到(INT),将其转换号码,如4.9994 ,所以你的结果1020636.999999999变为1020636(INT)计数。

When you care about the precision involved you should use the bcmul() function.当您关心所涉及的精度时,您应该使用bcmul()函数。 It's an "optional" extension, but if you care about precision it starts being required rather quickly.这是一个“可选”扩展,但如果你关心精度,它很快就会被要求。

Example:例子:

multiplier = 100000000;
$value = 0.01020637;
echo bcmul($value, $multiplier, 0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM