5

PHPで最も近い有効数字に切り捨てる巧妙な方法はありますか?

それで:

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

4

8 に答える 8

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

残念ながら、$ numberが0の場合、これはひどく失敗しますが、正の整数に対して期待される結果を生成します。そして、それは数学のみの解決策です。

于 2011-04-29T16:31:59.483 に答える
4

これが純粋数学の解決策です。これは、単に切り下げるだけでなく、切り上げまたは切り下げたい場合にも、より柔軟なソリューションです。そしてそれは0で動作します:)

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

またはに置き換えることができfloorます。実際、最も近い値に丸めたい場合は、3行目をさらに単純化できます。roundceil

$num = round($num, -$digits);
于 2011-04-29T16:34:09.023 に答える
3

マシーな解決策が必要な場合は、次のことを試してください。

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

    $nearest = pow(10, floor(log($int, 10)));
    return floor($int / $nearest) * $nearest;
}
于 2011-04-29T16:20:28.697 に答える
1

このようなもの:

$str = (string)$value;
echo (int)($str[0] . str_repeat('0', strlen($str) - 1));
于 2011-04-29T16:17:53.633 に答える
1

それは完全に数学的ではありませんが、私は刺し傷の長さを利用してこれを行うでしょう...おそらくそれを処理するためのよりスムーズな方法がありますが、あなたはそれを達成することができます

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;
}
于 2011-04-29T16:20:40.213 に答える
1

数学ベースの代替案:

$mod = pow(10, intval(round(log10($value) - 0.5))); 
$answer = ((int)($value / $mod)) * $mod;
于 2011-04-29T16:59:30.803 に答える
1

私はこれが古いスレッドであることを知っていますが、この問題を解決する方法についてのインスピレーションを探すときに読んでいます。これが私が思いついたものです:

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); 
    }
}
于 2015-12-19T00:06:14.863 に答える
0

ここでの機能は機能していましたが、非常に小さい数値には有効数字が必要でした(価値の低い暗号通貨とビットコインを比較して)。

PHPの有効数字N桁に対するフォーマット番号の答えはある程度機能しましたが、PHPでは科学的記数法で非常に小さい数値が表示されるため、一部の人にとっては読みづらくなります。

ここに画像の説明を入力してください

number_formatを使用してみましたが、小数点以下の特定の桁数が必要です。これにより、数値の「重要な」部分が壊れ(設定された数値が入力された場合)、0が返されることがありました(設定された数値よりも小さい数値の場合)。

解決策は、関数を変更して非常に小さい数を識別し、それらにnumber_formatを使用することでした-科学的記数法の桁数を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;
}

この関数は、有効数字を保持するだけでなく、すべての人に読みやすい形式で数値を表示します。(私は知っています、それは科学者にとっても、最も一貫した長さの「きれいな」見た目の数字でさえも最善ではありませんが、私たちが必要としたものにとって全体的に最良の解決策です。)

ここに画像の説明を入力してください

于 2018-02-18T17:49:30.890 に答える