Как получить число с плавающей запятой при делении двух целых чисел? (PHP)

Привет, я пытаюсь разделить два целых числа, например: 12/13, но я всегда получаю целое число 1, а не десятичное число.

Я безуспешно пытался ввести значения для плавания заранее.

В основном все, что я хочу, это десятичный результат, например: 0,923...

$x = 12;
$y = 13;
echo $value = $x / $y; //Would like to see 0.923 not 1

person user1869257    schedule 20.06.2013    source источник
comment
Я получаю 0.92307692307692, когда запускаю это   -  person Samuel Cook    schedule 20.06.2013
comment
проверьте свой php.ini на принудительный десятичный счет с плавающей запятой или точность, что-то вроде этого, не могу вспомнить, как оно называется.   -  person Dave    schedule 20.06.2013
comment
Какую версию PHP вы используете? php -v или phpinfo();   -  person Jason McCreary    schedule 20.06.2013
comment
Это ваш реальный код, или вы пытались упростить его перед публикацией? Вы действительно получаете 1 с этим экстрактом?   -  person Barmar    schedule 20.06.2013


Ответы (4)


В нормальных условиях ваш код должен возвращать плавающее значение 0.923076...

Причина, по которой вы получаете округленное целое число, может заключаться в том, что ваш ini setting для "precision" установлен на 0, чтобы исправить это, отредактируйте php.ini или используйте ini_set("precision", 3); в своем коде перед вычислением.

Другой способ обойти это — использовать BCmath:

echo $value=bcdiv($a, $b, 3);

И еще один способ без использования каких-либо расширений состоит в том, чтобы использовать небольшой математический трюк, умножив значение, которое вы хотите разделить, на 1000, чтобы получить 3 decimals.
Таким образом, вы разделите 12000 на 13, и вся часть будет 923, тогда так как вы умножили на 1e3, вставьте запятую/точку перед последними тремя знаками.

function divideFloat($a, $b, $precision=3) {
    $a*=pow(10, $precision);
    $result=(int)($a / $b);
    if (strlen($result)==$precision) return '0.' . $result;
    else return preg_replace('/(\d{' . $precision . '})$/', '.\1', $result);
}

echo divideFloat($a, $b); // 0.923

person CSᵠ    schedule 20.06.2013
comment
Нет. С точностью 0 у нас есть 0.9.php.net/manual /en/ini.core.php#ini.precision недостаточно ясен; более подробное объяснение: PHP использует собственную реализацию разбора строки ((v)s)printf. В строке формата используется режим %H: он вызывает с параметром mode, установленным в 2, функцию zend_dtoa, в которой указана документация: [mode] 2 ==> max(1,ndigits) significant digits. This gives a return value similar to that of ecvt, except that trailing zeros are suppressed. (см.: lxr.php.net/xref/PHP_TRUNK/Zend/zend_strtod.c#1457)) Вот почему precision=1 == precision=0. - person bwoebi; 20.06.2013

echo $value = $x / (float) $y;

если вы присвоите переменной $y значение с плавающей запятой, интерпретатор будет использовать деление с плавающей запятой вместо целочисленного деления.

потому что по умолчанию предполагается использовать целочисленное деление для двух целочисленных переменных.

Было бы иначе, если бы вы использовали $y = 13.0 (переменная с плавающей запятой в качестве знаменателя): результаты всегда представляют собой число с плавающей запятой.

person Raffaello    schedule 23.01.2014
comment
Пожалуйста, объясните, как ваш ответ решает проблему, чтобы будущие посетители могли извлечь пользу из этого вопроса. - person War10ck; 23.01.2014

Все остальные ответы НЕ ПРАВИЛЬНЫ, потому что деление PHP всегда будет возвращать значения с плавающей запятой, как четко указано в официальном руководстве PHP: арифметические операторы , за исключением случаев, когда два операнда являются целыми числами, которые можно разделить нацело.

На самом деле вопрос неверный: код должен выдавать 0,923..., как и ожидалось от вопрошающего.

Саркастически, ответ, за который проголосовали (пришел от @BulletProof47), является единственным другим, который просто НЕ НЕПРАВИЛЬНЫЙ (но также бессмысленный). Кто знает, о чем он думал, но держу пари, все знают, почему за него проголосовали: D

В случае, если кому интересно, базовая функция, которая выполняет деление в php, — это div_function, расположенная в Zend/zend_operators.c, как показано ниже:

ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
{
    zval op1_copy, op2_copy;
    int converted = 0;

    while (1) {
        switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
            case TYPE_PAIR(IS_LONG, IS_LONG):
                if (Z_LVAL_P(op2) == 0) {
                    zend_error(E_WARNING, "Division by zero");
                    ZVAL_BOOL(result, 0);
                    return FAILURE;         /* division by zero */
                } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
                    /* Prevent overflow error/crash */
                    ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
                    return SUCCESS;
                }
                if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
                    ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
                } else {
                    ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
                }
                return SUCCESS;
    ...
person felix021    schedule 04.12.2015

Просто используйте $value = (float)($x/$y); //Результат будет в float.

Ваше здоровье!

person BulletProof47    schedule 20.06.2013
comment
- ОП упомянул попытку приведения типов. - person Jason McCreary; 20.06.2013