Question

Est-il possible de marée noire vers le bas autour de la figure significatif le plus proche en php?

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

Était-ce utile?

La solution

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

Malheureusement, cela ne fonctionne pas horriblement quand $ nombre est 0, mais il produit le résultat attendu pour les entiers positifs. Et il est une solution mathématique uniquement.

Autres conseils

Voici une solution pure mathématique. Ceci est également une solution plus souple si vous avez toujours voulu monter ou descendre rond, et pas seulement vers le bas. Et cela fonctionne sur 0:)

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

Vous pourriez remplacer floor avec round ou ceil. En fait, si vous vouliez arrondir au plus proche, vous pouvez simplifier la troisième ligne encore plus.

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

Si vous voulez avoir une solution mathy, essayez ceci:

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

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

Quelque chose comme ceci:

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

Il est tout à fait non-mathy, mais je voudrais juste faire en utilisant la longueur ... piquer il y a probablement une manière plus douce à manipuler mais vous pouvez acomplish avec

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

Un calcul basé alternatif:

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

Je sais que c'est un vieux fil, mais je l'ai lu lors de la recherche d'inspiration sur la façon de résoudre ce problème. Voici ce que je suis venu avec:

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

Alors que les fonctions ici ont travaillé, je avais besoin de chiffres significatifs pour de très petits nombres (comparant à Bitcoin faible crypto-monnaie valeur).

La réponse à numéro de format à N chiffres significatifs en PHP travaillé, un peu, bien que très petit nombre sont affichés par PHP en notation scientifique, ce qui les rend difficile pour certaines personnes à lire.

J'ai essayé d'utiliser number_format, mais qui a besoin d'un nombre spécifique de chiffres après la virgule, qui a cassé la partie « significative » du nombre (si un numéro de série est entré) et parfois retourné 0 (pour un nombre inférieur au nombre fixé ).

La solution a été de modifier la fonction pour identifier les numéros vraiment petits et utiliser number_format sur eux - en prenant le nombre de chiffres de notation scientifique que le nombre de chiffres pour 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;
}

Cette fonction conserve les chiffres significatifs ainsi que présente les numéros en format facile à lire pour tout le monde. (Je sais, ce n'est pas le meilleur pour les scientifiques, ni même les plus constamment longueur « jolie » chiffres à la recherche, mais il est globalement la meilleure solution pour ce que nous avions besoin.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top