2008-10-23 10 views
10

Gibt es eine Bibliotheksfunktion für diesen Zweck, also tue ich es nicht von Hand und riskiere das Ende in TDWTF?Wie man eine bcmath Zahl in PHP rundet/cill/flood?

echo ceil(31497230840470473074370324734723042.6); 

// Expected result 
31497230840470473074370324734723043 

// Prints 
<garbage> 
+0

Siehe auch meine weitere Frage: http://stackoverflow.com/questions/1642614/how-to-ceil-floor-and-round-bcmath-numbers –

Antwort

7

Dies wird für Sie arbeiten:

$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); 
} 

Grundsätzlich findet es die flooy durch durch eine mit Null Genauigkeit multipliziert wird.

Dann kann es ceil/Runde tun, indem sie die von der gesamten Subtrahieren, in Funktionen der eingebauten Aufruf, dann das Ergebnis wieder auf

Edit: Fest für -ve Zahlen

+0

+1 , aber es könnte sich lohnen, ein Maßstabsargument zu bcCeil und bcRound hinzuzufügen, da das Verhalten vom Maßstab abhängt. Wenn Sie 'bcscale (0)' aufrufen und dann bcCeil ('1.1') versuchen, erhalten Sie '1' und nicht '2', wie Sie vielleicht erwarten. Die Angabe der Skalierung würde mit den anderen BCMath-Funktionen konsistent sein. –

+0

Beachten Sie auch, dass das scale-Argument standardmäßig null sein sollte und den durch "bcscale" gesetzten Wert nicht überschreiben sollte, wenn dies nicht angegeben wird. –

13

UPDATE: Siehe mein verbesserte Antwort hier: How to ceil, floor and round bcmath numbers?.


Diese Funktionen scheinen mehr Sinn zu machen, zumindest für mich:

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); 
} 

Sie unterstützen negative Zahlen und die Präzision Argument für die bcround() Funktion.

Einige 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 
+0

Funktioniert nicht mit ganzen Zahlen. Gute Umsetzung dieser Funktionen hier: http://stackoverflow.com/a/1653826/541961 Alix, können Sie Ihren Beitrag bearbeiten, um den neueren zu verknüpfen. – Dmitriy

+1

@Dmitriy: Fertig. Vielen Dank. –

Verwandte Themen