Question

Existe-t-il une fonction de bibliothèque à cette fin, aussi je ne le fais pas à la main et je risquerais de finir en TDWTF?

echo ceil(31497230840470473074370324734723042.6);

// Expected result
31497230840470473074370324734723043

// Prints
<garbage>
Était-ce utile?

La solution

Cela fonctionnera pour vous:

$x = '31497230840470473074370324734723042.9';

bcscale(100);
var_dump(bcFloor($x));
var_dump(bcCeil($x));
var_dump(bcRound($x));

function bcFloor($x)
{
    $result = bcmul($x, '1', 0);
    if ((bccomp($result, '0', 0) == -1) && bccomp($x, $result, 1))
        $result = bcsub($result, 1, 0);

    return $result;
}

function bcCeil($x)
{
    $floor = bcFloor($x);
    return bcadd($floor, ceil(bcsub($x, $floor)), 0);
}

function bcRound($x)
{
    $floor = bcFloor($x);
    return bcadd($floor, round(bcsub($x, $floor)), 0);
}

En gros, il trouve le flotteur en le multipliant par un avec une précision nulle.

Ensuite, il peut arrondir ce seuil en le soustrayant du total, en appelant les fonctions intégrées, puis en rajoutant le résultat

Édition: corrigé pour -ve nombres

Autres conseils

UPDATE: voir ma réponse améliorée ici: Comment calculer, arrondir et arrondir les nombres? .

Ces fonctions semblent avoir plus de sens, du moins pour moi:

function bcceil($number)
{
    if ($number[0] != '-')
    {
        return bcadd($number, 1, 0);
    }

    return bcsub($number, 0, 0);
}

function bcfloor($number)
{
    if ($number[0] != '-')
    {
        return bcadd($number, 0, 0);
    }

    return bcsub($number, 1, 0);
}

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

    return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
}

Ils prennent en charge les nombres négatifs et l'argument de précision pour la fonction bcround ().

Quelques tests:

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.3') == floor('4.3')); // true
assert(bcfloor('9.999') == floor('9.999')); // true
assert(bcfloor('-3.14') == floor('-3.14')); // 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

OK, pour ma bibliothèque Money haute précision , à savoir actuellement sur des centaines de sites de production, j'ai dû réécrire complètement cette fonctionnalité. Rien de ce que j'ai trouvé sur Internet n’était à la mesure du code.

Voici ce que j'ai proposé:

/**
 * Based off of https://stackoverflow.com/a/1653826/430062
 * Thanks, [Alix Axel](https://stackoverflow.com/users/89771/alix-axel)!
 *
 * @param $number
 * @param int $precision
 * @return string
 */
function bcround($number, $precision = BCMathCalcStrategy::PRECISION)
{
    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);
    }

    // Pad it out to the desired precision.
    return number_format($number, $precision);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top