ich habe einen Wert in PHP-Variable so
$var='2.500000550';
echo $var
ich möchte alle Dezimalstellen nach 2 Ziffern löschen.
wie jetzt wird der Wert der Variablen sein
$var='2.50';
echo $var
denken Sie daran, dass dieser Wert von mysql databse stammt
aber wenn ich round php function
benutze, bin ich rund geworden, aber ich brauche nicht rund, ich muss einfach alle Ziffern nach 2 dezimal löschen.
ich habe müde, flot()
und viele andere Optionen keinen Erfolg.
Vielen Dank
Die PHP native Funktion bcdiv scheint genau das zu tun, was erforderlich ist, und zwar ordnungsgemäß.
Um eine Zahl einfach "abzuschneiden", ist bcdiv($var, 1, 2);
, wobei 2 die Anzahl der zu speichernden Dezimalstellen ist (und 1 der Denomenator ist - durch die Division durch 1 können Sie die ursprüngliche Zahl einfach auf die gewünschten Dezimalstellen abschneiden).
Dies stellt sich als schwieriger heraus, als man denkt.
Nachdem diese Antwort (falsch) ziemlich positiv war, ist mir aufgefallen, dass auch Sprintf rund wird.
Anstatt diese Antwort zu löschen, verwandle ich sie in eine robustere Erklärung/Diskussion jeder vorgeschlagenen Lösung.
number_format - Falsch. (Runden)
Versuchen Sie es mit Zahlenformat :
$var = number_format($var, 2, '.', ''); // Last two parameters are optional
echo $var;
// Outputs 2.50
Wenn Sie möchten, dass es sich um eine Zahl handelt, tippen Sie einfach in einen Float-Typ:
$var = (float)number_format($var, 2, '.', '');
Anmerkung: Wie in den Kommentaren darauf hingewiesen wurde, ist dies round die Zahl.
sprintf - falsch (sprintf auch Runden)
Wenn es nicht wichtig ist, die Zahl zu runden, verwenden Sie sprintf für die Antwort unten.
$var = sprintf("%01.2f", $var);
Boden - nicht ganz! (Boden rundet negative Zahlen)
floor wird mit etwas Mathe das tun, was Sie wollen:
floor(2.56789 * 100) / 100; // 2.56
Dabei steht 100 für die von Ihnen gewünschte Präzision. Wenn Sie drei Ziffern haben wollten, dann:
floor(2.56789 * 1000) / 1000; // 2.567
Dies hat jedoch ein Problem mit negativen Zahlen. Negative Zahlen werden immer noch gerundet und nicht abgeschnitten:
floor(-2.56789 * 100) / 100; // -2.57
Eine absolut robuste Lösung erfordert also eine Funktion:
function truncate_number( $number, $precision = 2) {
// Zero causes issues, and no need to truncate
if ( 0 == (int)$number ) {
return $number;
}
// Are we negative?
$negative = $number / abs($number);
// Cast the number to a positive to solve rounding
$number = abs($number);
// Calculate precision number for dividing / multiplying
$precision = pow(10, $precision);
// Run the math, re-applying the negative value to ensure returns correctly negative / positive
return floor( $number * $precision ) / $precision * $negative;
}
Ergebnisse aus der obigen Funktion:
echo truncate_number(2.56789, 1); // 2.5
echo truncate_number(2.56789); // 2.56
echo truncate_number(2.56789, 3); // 2.567
echo truncate_number(-2.56789, 1); // -2.5
echo truncate_number(-2.56789); // -2.56
echo truncate_number(-2.56789, 3); // -2.567
Verwenden Sie die native Funktion PHP bcdiv
echo bcdiv(2.56789, 1, 1); // 2.5
echo bcdiv(2.56789, 1, 2); // 2.56
echo bcdiv(2.56789, 1, 3); // 2.567
echo bcdiv(-2.56789, 1, 1); // -2.5
echo bcdiv(-2.56789, 1, 2); // -2.56
echo bcdiv(-2.56789, 1, 3); // -2.567
floor(2.500000550 * 100) / 100;
Das sollte deine Aufgabe erledigen ...
Sie fordern eine Funktion an, die "2.50"
Und nicht 2.5
Zurückgibt, also Sie sprechen nicht von Arithmetik hier aber String-Manipulation =. Dann ist preg_replace
Dein Freund:
$truncatedVar = preg_replace('/\.(\d{2}).*/', '.$1', $var);
// "2.500000050" -> "2.50", "2.509" -> "2.50", "-2.509" -> "2.50", "2.5" -> "2.5"
Wenn du es mit Arithmetik machen willst, benutze einfach:
$truncatedVar = round($var * 100) / 100);
// "2.500000050" -> "2.5", "2.599" -> "2.59", "-2.599" -> "2.59"
versuchen Sie es mit number_format :
echo number_format('2.50000050', 2); // 2.50
number_format rundet die Nummer
php > echo number_format(128.20512820513, 2)."\n";
128.21
Ich habe preg_replace verwendet, um die Zeichenfolge wirklich zu schneiden
php > echo preg_replace('/(\.\d\d).*/', '$1', 128.20512820513)."\n";
128.20
benutze sprintf
sprintf("%01.2f", $var);
Verwenden Sie die native Funktion PHP bcdiv .
Beispiel:
echo bcdiv(3.22871, 1, 1); // 3.2
echo bcdiv(3.22871, 1, 2); // 3.22
echo bcdiv(3.22871, 1, 3); // 3.228
echo bcdiv(-3.22871, 1, 1); // -3.2
echo bcdiv(-3.22871, 1, 2); // -3.22
Für Ihren Fall:
$var='2.500000550';
echo $var
echo bcdiv($var, 1, 2); // 2.50
jemand hier gepostet über
boden (2.500000550 * 100)/100;
function cutAfterDot($number, $afterDot = 2){
$a = $number * pow(10, $afterDot);
$b = floor($a);
$c = pow(10, $afterDot);
echo "a $a, b $b, c $c<br/>";
return $b/$c ;
}
echo cutAfterDot(2.05,2);
a 205, b 204, c 100
2.04
also in roher Form nicht verwenden ....... aber wenn Sie ein wenig Epsilon hinzufügen ...
function cutAfterDot($number, $afterDot = 2){
return floor($number * pow(10, $afterDot) + 0.00001) / pow(10, $afterDot);
}
es klappt!
Wenn Sie die Zahl nicht runden, aber die Nachkommastellen entfernen möchten, können Sie die Methode "substr" verwenden
substr(string, start, length);
substr(4.96, 0, -1);
boden - nicht ganz! (Boden rundet negative Zahlen)
Eine mögliche Lösung von cale_b answer.
static public function rateFloor($rate, $decimals)
{
$div = "1" . str_repeat("0", $decimals);
if ($rate > 0) {
return floor($rate * $div) / $div;
}
$return = floor(abs($rate) * $div) / $div;
return -($return);
}
static public function rateCeil($rate, $decimals)
{
$div = "1" . str_repeat("0", $decimals);
if ($rate > 0) {
return ceil($rate * $div) / $div;
}
$return = ceil(abs($rate) * $div) / $div;
return -($return);
}
Positiv
Rate: 0,00302471
Etage: 0,00302400
Decke: 0,00302500
Negativ
Rate: -0,00302471
Etage: -0,00302400
Decke: -0,00302500
Alle Lösungen, die number_format verwenden, sind falsch, da number_format eine Rundung durchführt.
Die folgende Funktion sollte für alle Zahlen funktionieren. Sie können das Dezimaltrennzeichen für die Länder angeben, in denen ',' verwendet wird.
function truncate_decimal($number, $truncate_decimal_length = 2, $decimal_character = '.', $thousands_character = '') {
$number = explode($decimal_character, $number);
$number[1] = substr($number[1], 0, $truncate_decimal_length);
$number_truncated = implode($decimal_character, $number);
return number_format($number_truncated, $truncate_decimal_length, $decimal_character, $thousands_character);
}
Eine einfache zu befolgende Funktion wäre "Wenn mehr als 0 Etage, sonst" "mit einem Multiplikator, um ihn vorübergehend über den Dezimalpunkt zu heben:
function trim_num($num_in, $dec_places = 2) {
$multiplier = pow(10, $dec_places); // 10, 100, 1000, etc
if ($num_in > 0) {
$num_out = floor($num_in * $multiplier) / $multiplier;
} else {
$num_out = ceil($num_in * $multiplier) / $multiplier;
}
return $num_out;
}
Das Folgende ist (was ich glaube - bitte korrigieren Sie mich wenn nicht) eine robuste mathematische * - Lösung, die hauptsächlich auf den Informationen einiger anderer Antworter basiert und eine kleine Menge von mir
(* Was nicht bedeutet, dass irgendetwas mit Liphtiers regexbasierter Antwort falsch ist - nur dass ich Puristen sehen kann, die Regex für ein wohl mathematisches Problem vermeiden wollen.)
sprintf()
, number_format()
(und natürlich round()
) führen alle eine Rundung durch und sind daher nicht für die in der Frage angeforderte Rundung geeignet (zumindest nicht für sich alleine).pow()
verwendet, um den richtigen Faktor basierend auf einer festgelegten Genauigkeit zu erhalten ).floor()
(oder vermutlich ceil()
) unbeabsichtigte Ergebnisse für Negative ohne abs()
ergeben.abs()
verwenden, um einen Negationsfaktor zu erhalten, müssen wir den Sonderfall berücksichtigen, wenn die Eingabe 0 ist.Der Code, den ich verwende, lautet:
public static function truncate_decimal($number, $leavePlaces = 2)
{
if ($number == 0) return 0;
$negate = $number / abs($number);
$shiftFactor = pow(10, $leavePlaces);
$epsilon = pow(10, -1 * $leavePlaces);
return floor(abs($number) * $shiftFactor + $epsilon) / $shiftFactor * $negate;
}
$num = 118.74999669307;
$cut = substr($num, 0, ((strpos($num, '.')+1)+2));
// Cut the string from first character to a length of 2 past the decimal.
// substr(cut what, start, ( (find position of decimal)+decimal itself)+spaces after decimal) )
echo $cut;