我的问题是:是否有一个很好的(通用)算法来创建数字,这些数字与用户理解的数字相匹配(从随机寻找用户的数字)数字。
即。你有一个间隔
130'777.12 - 542'441.17
。
但是对于用户来说,你想要展示更多东西...说用户友好,比如:
130'000 - 550'000
。
你怎么能在几个方面做到这一点? 另一个例子是:
23.07 - 103.50
至20 - 150
我也应该给出一些标准:
20 - 200
会太粗糙了)*更新 - 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;
}
答案 0 :(得分:5)
我会使用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看起来有点“圆”。为了达到这样的结果,我建议使用quinary system而不是decimal。
答案 1 :(得分:4)
你可以使用php的round
函数,它接受一个参数来指定精度。
<?php
echo round(3.4); // 3
echo round(3.5); // 4
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2); // 5.05
echo round(5.055, 2); // 5.06
?>
答案 2 :(得分:1)
number_format()
函数使用任意数千/十进制字符和小数位来处理“美化”数字,但是您必须将范围/字符串拆分为单个数字,因为number_formation一次只能处理一个数字
圆角部分也必须单独处理。
答案 3 :(得分:0)
我还没有看到准备好的算法或功能。但它应该很简单,基于字符串替换(str_replace
,preg_replace
),number_format
和round
函数。
答案 4 :(得分:0)
这实际上是一种特殊情况,可以使用以下功能解决:
function roundto($val, $toceil=false) {
$precision=2; // try 1, 2, 5, 10
$pow = floor(log($val, 10));
$mult = pow(10, $pow);
$a = $val/$mult*$precision;
if (!$toceil) $a-=0.5; else $a+=0.5;
return round($a)/$precision*$mult;
}
$v0=130777.12; $v1=542441.17;
echo number_format(roundto($v0, false), 0, '.', "'").' - '
.number_format(roundto($v1, true), 0, '.', "'").'<br/>';
$v0=23.07; $v1=103.50;
echo number_format(roundto($v0, false), 0, '.', "'").' - '
.number_format(roundto($v1, true), 0, '.', "'").'<br/>';
确切地输出以下内容:
100'000 - 550'000
20 - 150
对于数字格式的其他任何情况,看看我新发布的PHP类“ php-beautiful-numbers”可能会很有趣,我几乎在所有项目中都使用它来显示运行时间(“ 98.4µµs” [= 9.8437291615846E-5])或连续文字中的数字(例如“您预订了两个航班。” [= 2])。