1. ホーム
  2. php

[解決済み] きれいな数字 "をつくるには?

2022-02-14 17:11:50

質問内容

私の質問は、インコム(ユーザーにとってランダムな)番号から、ユーザーが理解できる番号に一致する番号を作成する良い(共通の)アルゴリズムがあるかということです。

例えば、次のような区間があるとします。

130'777.12 - 542'441.17 .

しかし、ユーザーにとっては、もっと......たとえば、ユーザーフレンドリーなものを表示したいと思うものです。

130'000 - 550'000 .

これを複数の次元で行うにはどうすればよいのでしょうか。 他の例としては

23.07 - 103.50 から 20 - 150

ということなんですが、わかりますか?

基準も示すべきでしょう。

  • 区間minとmaxは は、与えられた制限を含んでいます。
  • 四捨五入は を反映した粒度です。 最小値と最大値の間の距離(つまり 2番目の例では 20 - 200 は粗すぎる)

これを実現するネイティブなphp関数をご存知でしたら、大変光栄です :-)

*更新日 - 2011-02-21

Ivanからの回答が気に入ったので、受け入れました。以下は、これまでの私の解決策です。

もっといい方法があるかもしれません。どんな提案でも歓迎します;-)

/**
 * formats a given float number to a well readable number for human beings
 * @author helle + ivan + greg
 * @param float $number 
 * @param boolean $min regulates wheter its the min or max of an interval
 * @return integer
 */
function pretty_number($number, $min){
    $orig = $number;
    $digit_count = floor(log($number,10))+1; //capture count of digits in number (ignoring decimals)
    switch($digit_count){
        case 0: $number = 0; break;
        case 1:
        case 2: $number = round($number/10) * 10; break;
        default: $number = round($number, (-1*($digit_count -2 )) ); break;
    }

    //be sure to include the interval borders
    if($min == true && $number > $orig){
        return pretty_number($orig - pow(10, $digit_count-2)/2, true);
    }

    if($min == false && $number < $orig){
        return pretty_number($orig + pow(10, $digit_count-2)/2, false);
    }

    return $number;

}

解決方法は?

Log10を使って、数字がどれくらい長いかを調べ、それを切り上げたり切り捨てたりするのです。 以下は、簡単な例です。

echo prettyFloor(23.07);//20
echo " - ";
echo prettyCeil(103.50);//110

echo prettyFloor(130777.12);//130000
echo " - ";
echo prettyCeil(542441.17);//550000

function prettyFloor($n)
{
  $l = floor(log(abs($n),10))-1; // $l = how many digits we will have to nullify :)
  if ($l<=0)
    $l++;

  if ($l>0)
    $n=$n/(pow(10,$l)); //moving decimal point $l positions to the left eg(if $l=2 1234 => 12.34 )
  $n=floor($n);
  if ($l>0)
    $n=$n*(pow(10,$l)); //moving decimal point $l positions to the right eg(if $l=2 12.3 => 1230 )
  return $n;
}

function prettyCeil($n)
{
  $l = floor(log(abs($n),10))-1;
  if ($l<=0)
    $l++;
  if ($l>0)
    $n=$n/(pow(10,$l));
  $n=ceil($n);
  if ($l>0)
    $n=$n*(pow(10,$l));
  return $n;
}

この例では、残念ながら130を150に変換することはできません。130も150も同じ精度だからです。私たち人間にとって、150は少し丸く見えますが。このような結果を得るためには、10進法の代わりに2進法を使用することをお勧めします。