Как преобразовать десятичные дроби в дроби в PHP - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь умножить числа на 2, и эти числа являются целыми числами или дробями. Я вытягиваю эти числа динамически через поля ACF на WordPress как текстовое поле. Но некоторые из этих динамических чисел c не являются дробными, а просто целыми числами, такими как 3 или 1. То, что я пытаюсь сделать, это удвоить число, так что 3/4 будет 1 1/2. Но когда я умножаю дробь на 3/4, она превращается в 1,5. Я использовал код fubars , чтобы эти числа оставались дробными, но затем я столкнулся с проблемой правильных дробей, отображаемых в виде десятичных дробей.

Когда вы нажимаете 6 в размере порции, он должен удвоить рецепт как дроби.

Вот фрагмент кода из моего шаблона, который заботится об этих числах (у меня 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; ?>

Будет для них лучше иметь значение в виде десятичных дробей, но каким-то образом использовать jQuery / javascript, чтобы преобразовать его в дроби только для внешнего интерфейса?

Мысли? Я был бы очень признателен!

Дайте мне знать.

Спасибо!

РЕДАКТИРОВАТЬ

Для тех, кто работает с полями ACF через WordPress, вот простое решение для этого. Поле $ 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;
}
}

Затем просто добавьте convert () вокруг значения $ number, которое вытягивается в шаблон WP, так что convert ($ номер).

Ответы [ 2 ]

1 голос
/ 14 января 2020

Если ваше числовое поле содержит дробное значение, PHP фактически будет считать его string, а не number, и поэтому его необходимо будет преобразовать в number, прежде чем вы сможете использовать чтобы выполнить арифметику c.

Поскольку вы обновили требования своего вопроса, я изменил свой ответ, включив в него две функции. Я написал одну функцию для преобразования дробного в десятичное значение, а другую - для преобразования десятичного в дробное значение.

Рабочий пример этого можно увидеть здесь: 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
0 голосов
/ 14 января 2020

Вы не умножаете ровно 100 на 0,1, а на 0.09999999998 ... И когда дело доходит до ( int ), оно конвертирует числа вроде 4.999 в 4, так что результат 1020636.999999999 становится 1020636 при подсчете с помощью ( int ).

Если вам нужна точность, вы должны использовать функцию bcmul () . Это «необязательное» расширение, но если вы заботитесь о точности, оно начинает требоваться довольно быстро.

Пример:

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