Как перекрыть, поставьте в тупик и вокруг bcmath числа?

Вы могли смотреть здесь для подробного объяснения.

Это может также помочь смотреть на прием, используемый в плоскости C для реализации некоторого основного вида обработки исключений. Это влечет за собой использование setjmp () и longjmp () следующим образом: первый сохраняет стек для маркировки обработчика исключений (как "выгода"), в то время как последний используется для "бросания" значения. "Брошенное" значение замечено, как будто оно было возвращено из вызванной функции. "Блок попытки" заканчивается, когда setjmp () называют снова или когда функция возвращается.

19
задан Community 23 May 2017 в 12:18
поделиться

2 ответа

После ночи, потерянной в попытках решить эту проблему, я считаю, что нашел довольно простое решение, вот оно:

function bcceil($number)
{
    if (strpos($number, '.') !== false) {
        if (preg_match("~\.[0]+$~", $number)) return bcround($number, 0);
        if ($number[0] != '-') return bcadd($number, 1, 0);
        return bcsub($number, 0, 0);
    }
    return $number;
}

function bcfloor($number)
{
    if (strpos($number, '.') !== false) {
        if (preg_match("~\.[0]+$~", $number)) return bcround($number, 0);
        if ($number[0] != '-') return bcadd($number, 0, 0);
        return bcsub($number, 1, 0);
    }
    return $number;
}

function bcround($number, $precision = 0)
{
    if (strpos($number, '.') !== false) {
        if ($number[0] != '-') return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
        return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
    }
    return $number;
}

Я думаю, что ничего не пропустил, если кто-то может обнаружить какую-либо ошибку пожалуйста, дай мне знать. Вот несколько тестов:

assert(bcceil('4') == ceil('4')); // true
assert(bcceil('4.3') == ceil('4.3')); // true
assert(bcceil('9.999') == ceil('9.999')); // true
assert(bcceil('-3.14') == ceil('-3.14')); // true

assert(bcfloor('4') == floor('4')); // true
assert(bcfloor('4.3') == floor('4.3')); // true
assert(bcfloor('9.999') == floor('9.999')); // true
assert(bcfloor('-3.14') == floor('-3.14')); // true

assert(bcround('3', 0) == number_format('3', 0)); // true
assert(bcround('3.4', 0) == number_format('3.4', 0)); // true
assert(bcround('3.5', 0) == number_format('3.5', 0)); // true
assert(bcround('3.6', 0) == number_format('3.6', 0)); // true
assert(bcround('1.95583', 2) == number_format('1.95583', 2)); // true
assert(bcround('5.045', 2) == number_format('5.045', 2)); // true
assert(bcround('5.055', 2) == number_format('5.055', 2)); // true
assert(bcround('9.999', 2) == number_format('9.999', 2)); // true
30
ответ дан 30 November 2019 в 04:07
поделиться

Here's ones that support negative numbers and precision argument for rounding.

function bcceil($val) {
    if (($pos = strpos($val, '.')) !== false) {
        if ($val[$pos+1] != 0 && $val[0] != '-')
            return bcadd(substr($val, 0, $pos), 1, 0);
        else
            return substr($val, 0, $pos);
    }
    return $val;
}

function bcfloor($val) {
    if (($pos = strpos($val, '.')) !== false) {
        if ($val[$pos+1] != 0 && $val[0] == '-')
            return bcsub(substr($val, 0, $pos), 1, 0);
        else
            return substr($val, 0, $pos);
    }
    return $val;
}

function bcround($val, $precision = 0) {
    if (($pos = strpos($val, '.')) !== false) {
        if ($precision > 0) {
            $int = substr($val, 0, $pos);
            $pos2 = ++$pos+$precision;
            if ($pos2 < strlen($val)) {
                $val2 = sprintf('%s.%s', substr($val, $pos, $pos2-$pos), substr($val, $pos2));
                $val2 = $val2[0] >= 5 ? bcceil($val2) : bcfloor($val2);
                if (strlen($val2) > $precision)
                    return bcadd($int, $val[0] == '-' ? -1 : 1, 0);
                else
                    return sprintf('%s.%s', $int, rtrim($val2, '0'));
            }
            return $val;
        } else {
            if ($val[$pos+1] >= 5)
                return ($val[0] == '-' ? bcfloor($val) : bcceil($val));
            else
                return ($val[0] == '-' ? bcceil($val) : bcfloor($val));
        }
    }
    return $val;
}
1
ответ дан 30 November 2019 в 04:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: