Frage

Gibt es einen glatten Weg, um die nächste signifikante Figur in PHP zu runden?

So:

0->0
9->9
10->10
17->10
77->70
114->100
745->700
1200->1000

?

War es hilfreich?

Lösung

$numbers = array(1, 9, 14, 53, 112, 725, 1001, 1200);
foreach($numbers as $number) {
    printf('%d => %d'
            , $number
            , $number - $number % pow(10, floor(log10($number)))
            );
    echo "\n";
}

Leider scheitert dies schrecklich, wenn $ Number 0 ist, aber es führt das erwartete Ergebnis für positive Ganzzahlen. Und es ist eine mathematische Lösung.

Andere Tipps

Hier ist eine reine Mathematiklösung. Dies ist auch eine flexiblere Lösung, wenn Sie sich jemals rund oder runter und nicht nur runter runden wollten. Und es funktioniert auf 0 :)

if($num === 0) return 0;
$digits = (int)(log10($num));
$num = (pow(10, $digits)) * floor($num/(pow(10, $digits)));

Sie könnten ersetzen floor mit round oder ceil. Wenn Sie auf die nächste runden wollten, können Sie die dritte Zeile noch mehr vereinfachen.

$num = round($num, -$digits);

Wenn Sie eine mathematische Lösung haben möchten, versuchen Sie Folgendes:

function floorToFirst($int) {
    if (0 === $int) return 0;

    $nearest = pow(10, floor(log($int, 10)));
    return floor($int / $nearest) * $nearest;
}

Etwas wie das:

$str = (string)$value;
echo (int)($str[0] . str_repeat('0', strlen($str) - 1));

Es ist total nicht mathisch, aber ich würde das einfach mit der Stachelänge tun ... es gibt wahrscheinlich eine reibungslosere Möglichkeit, damit umzugehen, aber Sie könnten es mit ihm unterhalten

function significant($number){
    $digits = count($number);
    if($digits >= 2){
        $newNumber = substr($number,0,1);
        $digits--;
        for($i = 0; $i < $digits; $i++){
            $newNumber = $newNumber . "0";
        }
    }
    return $newNumber;
}

Eine mathematische Alternative:

$mod = pow(10, intval(round(log10($value) - 0.5))); 
$answer = ((int)($value / $mod)) * $mod;

Ich weiß, dass dies ein alter Thread ist, aber ich habe ihn gelesen, wenn ich nach Inspiration suche, wie man dieses Problem lösen kann. Folgendes habe ich mir ausgedacht:

class Math
{
    public static function round($number, $numberOfSigFigs = 1)
    {
        // If the number is 0 return 0
        if ($number == 0) {
            return 0;
        }

        // Deal with negative numbers
        if ($number < 0) {
            $number = -$number;
            return -Math::sigFigRound($number, $numberOfSigFigs);
        }

        return Math::sigFigRound($number, $numberOfSigFigs);
    }

    private static function sigFigRound($number, $numberOfSigFigs)
    {
        // Log the number passed
        $log = log10($number);

        // Round $log down to determine the integer part of the log
        $logIntegerPart = floor($log);

        // Subtract the integer part from the log itself to determine the fractional part of the log
        $logFractionalPart = $log - $logIntegerPart;

        // Calculate the value of 10 raised to the power of $logFractionalPart
        $value = pow(10, $logFractionalPart);

        // Round $value to specified number of significant figures
        $value = round($value, $numberOfSigFigs - 1);

        // Return the correct value
        return $value * pow(10, $logIntegerPart); 
    }
}

Während die hier funktionierten Funktionen, brauchte ich erhebliche Ziffern für sehr kleine Zahlen (verglichene Kryptowährung mit niedrigem Wert mit Bitcoin).

Die Antwort bei Formatzahl zu n signifikanten Ziffern in PHP etwas funktioniert, etwas, obwohl sehr kleine Zahlen von PHP in wissenschaftlicher Notation angezeigt werden, was sie für manche Menschen schwer zu lesen macht.

enter image description here

Ich habe versucht, Number_Format zu verwenden, obwohl nach dem Dezimal eine bestimmte Anzahl von Ziffern erforderlich ist, was den "signifikanten" Teil der Zahl (wenn eine festgelegte Nummer eingegeben wurde) und manchmal 0 zurückgegeben wurde (für Zahlen kleiner als die festgelegte Nummer).

Die Lösung bestand darin, die Funktion zu ändern, um wirklich kleine Zahlen zu identifizieren und dann Number_Format zu verwenden - die Anzahl der wissenschaftlichen Notationsstellen als Anzahl der Ziffern für Number_Format:

function roundRate($rate, $digits)
{
    $mod = pow(10, intval(round(log10($rate))));
    $mod = $mod / pow(10, $digits);
    $answer = ((int)($rate / $mod)) * $mod;
    $small = strstr($answer,"-");
    if($small)
    {
        $answer = number_format($answer,str_replace("-","",$small));
    }
    return $answer;
}

Diese Funktion behält die wesentlichen Ziffern bei und präsentiert die Zahlen im einfach zu lesenden Format für alle. (Ich weiß, es ist nicht das Beste für wissenschaftliche Menschen und sogar die durchweg längsten "hübschen" Zahlen, aber es ist insgesamt die beste Lösung für das, was wir brauchten.)

enter image description here

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top