round

(PHP 4, PHP 5, PHP 7, PHP 8)

round舍入浮点数

描述

round(int|float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): float

num 舍入到指定的 precision(小数点后的位数)。precision 也可以是负数或零(默认)。

参数

num

要舍入的值。

precision

可选的小数位数。

如果 precision 为正数,则将 num 舍入到小数点后 precision 位有效数字。

如果 precision 为负数,则将 num 舍入到小数点前 precision 位有效数字,即舍入到 pow(10, -$precision) 的最近倍数,例如,对于 precision 为 -1,num 舍入到十位,对于 precision 为 -2 舍入到百位,等等。

mode

使用以下常量之一来指定舍入发生的模式。

常量 描述
PHP_ROUND_HALF_UP num 处于一半时,将 num 舍入为远离零的值,使 1.5 成为 2,-1.5 成为 -2。
PHP_ROUND_HALF_DOWN num 处于一半时,将 num 舍入为靠近零的值,使 1.5 成为 1,-1.5 成为 -1。
PHP_ROUND_HALF_EVEN num 处于一半时,将 num 舍入为最接近的偶数值,使 1.5 和 2.5 都成为 2。
PHP_ROUND_HALF_ODD num 处于一半时,将 num 舍入为最接近的奇数值,使 1.5 成为 1,2.5 成为 3。

返回值

舍入到指定 precision 的值,以 float 类型返回。

变更日志

版本 描述
8.0.0 num 不再接受支持数字转换的内部对象。

示例

示例 #1 round() 示例

<?php
var_dump
(round(3.4));
var_dump(round(3.5));
var_dump(round(3.6));
var_dump(round(3.6, 0));
var_dump(round(5.045, 2));
var_dump(round(5.055, 2));
var_dump(round(345, -2));
var_dump(round(345, -3));
var_dump(round(678, -2));
var_dump(round(678, -3));
?>

上面的示例将输出

float(3)
float(4)
float(4)
float(4)
float(5.05)
float(5.06)
float(300)
float(0)
float(700)
float(1000)

示例 #2 precision 如何影响浮点数

<?php
$number
= 135.79;

var_dump(round($number, 3));
var_dump(round($number, 2));
var_dump(round($number, 1));
var_dump(round($number, 0));
var_dump(round($number, -1));
var_dump(round($number, -2));
var_dump(round($number, -3));
?>

上面的示例将输出

float(135.79)
float(135.79)
float(135.8)
float(136)
float(140)
float(100)
float(0)

示例 #3 mode 示例

<?php
echo '舍入模式,值为 9.5' . PHP_EOL;
var_dump(round(9.5, 0, PHP_ROUND_HALF_UP));
var_dump(round(9.5, 0, PHP_ROUND_HALF_DOWN));
var_dump(round(9.5, 0, PHP_ROUND_HALF_EVEN));
var_dump(round(9.5, 0, PHP_ROUND_HALF_ODD));

echo
PHP_EOL;
echo
'舍入模式,值为 8.5' . PHP_EOL;
var_dump(round(8.5, 0, PHP_ROUND_HALF_UP));
var_dump(round(8.5, 0, PHP_ROUND_HALF_DOWN));
var_dump(round(8.5, 0, PHP_ROUND_HALF_EVEN));
var_dump(round(8.5, 0, PHP_ROUND_HALF_ODD));
?>

上面的示例将输出

Rounding modes with 9.5
float(10)
float(9)
float(10)
float(9)

Rounding modes with 8.5
float(9)
float(8)
float(8)
float(9)

示例 #4 modeprecision 示例

<?php
echo '使用 PHP_ROUND_HALF_UP 进行小数点后一位精度四舍五入' . PHP_EOL;
var_dump(round( 1.55, 1, PHP_ROUND_HALF_UP));
var_dump(round(-1.55, 1, PHP_ROUND_HALF_UP));

echo
PHP_EOL;
echo
'使用 PHP_ROUND_HALF_DOWN 进行小数点后一位精度四舍五入' . PHP_EOL;
var_dump(round( 1.55, 1, PHP_ROUND_HALF_DOWN));
var_dump(round(-1.55, 1, PHP_ROUND_HALF_DOWN));

echo
PHP_EOL;
echo
'使用 PHP_ROUND_HALF_EVEN 进行小数点后一位精度四舍五入' . PHP_EOL;
var_dump(round( 1.55, 1, PHP_ROUND_HALF_EVEN));
var_dump(round(-1.55, 1, PHP_ROUND_HALF_EVEN));

echo
PHP_EOL;
echo
'使用 PHP_ROUND_HALF_ODD 进行小数点后一位精度四舍五入' . PHP_EOL;
var_dump(round( 1.55, 1, PHP_ROUND_HALF_ODD));
var_dump(round(-1.55, 1, PHP_ROUND_HALF_ODD));
?>

上面的示例将输出

Using PHP_ROUND_HALF_UP with 1 decimal digit precision
float(1.6)
float(-1.6)

Using PHP_ROUND_HALF_DOWN with 1 decimal digit precision
float(1.5)
float(-1.5)

Using PHP_ROUND_HALF_EVEN with 1 decimal digit precision
float(1.6)
float(-1.6)

Using PHP_ROUND_HALF_ODD with 1 decimal digit precision
float(1.5)
float(-1.5)

另请参阅

添加备注

用户贡献的备注 32 个备注

takingsides at gmail dot com
10 年前
在我看来,此函数缺少两个标志

- PHP_ROUND_UP - 始终向上取整。
- PHP_ROUND_DOWN - 始终向下取整。

在会计中,通常需要始终向上或向下取整到千分位的精度。

<?php
function round_up($number, $precision = 2)
{
$fig = (int) str_pad('1', $precision, '0');
return (
ceil($number * $fig) / $fig);
}

function
round_down($number, $precision = 2)
{
$fig = (int) str_pad('1', $precision, '0');
return (
floor($number * $fig) / $fig);
}
?>
depaula at unilogica dot com
7 年前
由于 PHP 没有原生数字截断函数,因此这是我的解决方案 - 一个在需要截断而不是四舍五入数字时可能很有用的函数。

<?php
/**
* 截断浮点数,例如: <code>truncate(-1.49999, 2); // 返回 -1.49
* truncate(.49999, 3); // 返回 0.499
* </code>
* @param float $val 要截断的浮点数
* @param int f 精度数
* @return float
*/
function truncate($val, $f="0")
{
if((
$p = strpos($val, '.')) !== false) {
$val = floatval(substr($val, 0, $p + 1 + $f));
}
return
$val;
}
?>

最初发布在 http://stackoverflow.com/a/12710283/1596489
slimusgm at gmail dot com
9 年前
如果您有负零,并且需要返回正数,只需添加 +0

$number = -2.38419e-07;
var_dump(round($number,1));//float(-0)
var_dump(round($number,1) + 0);//float(0)
Mojo urk
6 年前
解决 round_down() 问题
-----------------------------
使用 <?php floor(pow(10, $precision) * $value) / pow(10, $precision); ?> 在某些情况下会失败,例如 round_down(2.05, 2) 会给出错误的 2.04。
以下是解决该问题的“字符串”解决方案(https://stackoverflow.com/a/26491492/1245149)(未涵盖负精度)

<?php
function round_down($value, $precision) {
$value = (float)$value;
$precision = (int)$precision;
if (
$precision < 0) {
$precision = 0;
}
$decPointPosition = strpos($value, '.');
if (
$decPointPosition === false) {
return
$value;
}
return (float)(
substr($value, 0, $decPointPosition + $precision + 1));
}
?>

解决 round_up() 问题
---------------------------
使用 <?php ceil(pow(10, $precision) * $value) / pow(10, $precision);?> 在某些情况下会失败,例如 round_up(2.22, 2) 会给出错误的 2.23(https://stackoverflow.com/a/8239620/1245149)。
通过调整上面的 round_down() “字符串”解决方案,我得到了以下结果(未涵盖负精度)

<?php
function round_up($value, $precision) {
$value = (float)$value;
$precision = (int)$precision;
if (
$precision < 0) {
$precision = 0;
}
$decPointPosition = strpos($value, '.');
if (
$decPointPosition === false) {
return
$value;
}
$floorValue = (float)(substr($value, 0, $decPointPosition + $precision + 1));
$followingDecimals = (int)substr($value, $decPointPosition + $precision + 1);
if (
$followingDecimals) {
$ceilValue = $floorValue + pow(10, -$precision); // 这是否总是给出正确的结果?
}
else {
$ceilValue = $floorValue;
}
return
$ceilValue;
}
?>

我不知道它是否万无一失,但至少它消除了上面提到的故障。我没有进行二进制到十进制数学分析,但如果`$floorValue + pow(10, 0 - $precision)` 始终按预期工作
那么它应该没问题。
serg at kalachev dot ru
9 年前
类似 Excel 的 ROUNDUP 函数

public static function round_up($value, $places)
{
$mult = pow(10, abs($places));
return $places < 0 ?
ceil($value / $mult) * $mult
ceil($value * $mult) / $mult;
}

echo round_up(12345.23, 1); // 12345.3
echo round_up(12345.23, 0); // 12346
echo round_up(12345.23, -1); // 12350
echo round_up(12345.23, -2); // 12400
echo round_up(12345.23, -3); // 13000
echo round_up(12345.23, -4); // 20000
jongbumi at gmail dot com
8 年前
PHP 5.3, 5.4, 5.5
<?php
$fInfinty
= pow(1000, 1000); // float(INF)
$fResult = round(123.456, $fInfinty); // double(123)
?>

PHP 5.6
<?php
$fInfinty
= pow(1000, 1000); // float(INF)
$fResult = round(123.456, $fInfinty); // float(0)
?>

PHP 7
<?php
$fInfinty
= pow(1000, 1000); // float(INF)
$fResult = round(123.456, $fInfinty); // null
?>
djcox99 at googlemail dot com
10 年前
我发现,在某些情况下,将数字转换为字符串后,使用 round 进行舍入可能会出现舍入错误。

为了解决这个问题,我用 number_format() 替换了 round()。

不幸的是,我无法提供示例(因为该数字无法表示为字符串!)

本质上,我使用的是 round(0.688888889,2);

它在打印为字符串时会保持为 0.68888889。

但使用 number_format,它会正确地变为 0.69。
esion99 at gmail dot com
10 年前
意外结果或误解 (php v5.5.9)

<?php

echo round(1.55, 1, PHP_ROUND_HALF_DOWN); // 1.5
echo round(1.551, 1, PHP_ROUND_HALF_DOWN); //1.6

?>
christian at deligant dot net
12 年前
此函数(以及所有数学运算符)会处理 setlocale 设置,这会导致在预期使用英语数学符号时出现一些奇怪的行为,例如在 width: 样式属性中打印结果!

<?php
$a
=3/4;
echo
round($a, 2); // 0.75

setlocale(LC_ALL, 'it_IT@euro', 'it_IT', 'it');
$b=3/4;
echo
round($b,2); // 0,75
?>
twan at ecreation dot nl
24 年前
如果您只想对显示的变量进行舍入(而不是对舍入后的结果进行计算),则应使用带有浮点数的 printf

<?php printf ("%6.2f",3.39532); ?>

这将返回:3.40 。
craft at ckdevelop dot org
10 年前
function mround($val, $f=2, $d=6){
return sprintf("%".$d.".".$f."f", $val);
}

echo mround(34.89999); //34.90
Anonymous
13 年前
以下是一个将数字舍入到指定增量的函数,但始终向上舍入。我不得不使用它来进行价格调整,价格总是向上调整到 5 美元的增量。

<?php
function roundUpTo($number, $increments) {
$increments = 1 / $increments;
return (
ceil($number * $increments) / $increments);
}
?>
michaeldnelson dot mdn at gmail dot com
14 年前
此函数允许您将数字舍入到任意非零数字。当然,零会导致除以零错误。

<?php
function roundTo($number, $to){
return
round($number/$to, 0)* $to;
}

echo
roundTo(87.23, 20); //80
echo roundTo(-87.23, 20); //-80
echo roundTo(87.23, .25); //87.25
echo roundTo(.23, .25); //.25
?>
greghenle at gmail dot com
7 年前
/**
* 舍入到第一个有效数字
* +N 到 +无穷大
* -N 到 -无穷大
*
*/
function round1stSignificant ( $N ) {
if ( $N === 0 ) {
return 0;
}

$x = floor ( log10 ( abs( $N ) ) );

return ( $N > 0 )
? ceil( $N * pow ( 10, $x * -1 ) ) * pow( 10, $x )
: floor( $N * pow ( 10, $x * -1 ) ) * pow( 10, $x );
}

echo round1stSignificant( 39144818 ) . PHP_EOL;
echo round1stSignificant( 124818 ) . PHP_EOL;
echo round1stSignificant( 0.07468 ) . PHP_EOL;
echo round1stSignificant( 0 ) . PHP_EOL;
echo round1stSignificant( -0.07468 ) . PHP_EOL;

/**
* 输出
*
* 40000000
* 200000
* 0.08
* 0
* -0.08
*
*/
dastra
12 年前
round() 在对浮点数进行舍入时,有时会返回 E 表示法,当金额足够小时 - 请参见 https://bugs.php.net/bug.php?id=44223 。显然这是一个功能。

为了在转换为字符串时解决此“功能”,请用 sprintf 包裹您的 round 语句

sprintf("%.10f", round( $amountToBeRounded, 10));
php at silisoftware dot com
22 年前
以下是一个将数字舍入到任意有效位数的函数。不要将其与舍入到负精度混淆 - 后者从小数点算起,而此函数从最高有效位算起。

例如

<?php
round
(1241757, -3); // 1242000
RoundSigDigs(1241757, 3); // 1240000
?>

对负数也适用。$sigdigs 应大于等于 0

<?php
function RoundSigDigs($number, $sigdigs) {
$multiplier = 1;
while (
$number < 0.1) {
$number *= 10;
$multiplier /= 10;
}
while (
$number >= 1) {
$number /= 10;
$multiplier *= 10;
}
return
round($number, $sigdigs) * $multiplier;
}
?>
martinr at maarja dot net
16 年前
请注意,此函数输出的格式也取决于您的区域设置。例如,如果您将区域设置设置为使用逗号分隔小数点的国家/地区,则此函数的输出也会使用逗号而不是点。

当您将舍入后的浮点数输入到需要使用点分隔小数点的数据库时,这可能会成为问题。

实际操作
<?php
echo round('3.5558', 2);
setlocale(constant('LC_ALL'), 'et_EE.UTF-8');
echo
'<br />'. round('3.5558', 2);
?>

输出将是
3.56
3,56
Anonymous
7 年前
请注意,PHP 5.3 不仅仅引入了 $mode,它还完全重写了舍入实现,以消除舍入浮点值时常见的许多舍入错误。

这就是为什么 round() 即使在 floor/ceil 不起作用时也能为您提供正确结果的原因。
例如,floor(0.285 * 100 + 0.5) VS round(0.285*100 + 0.5)。第一个结果为 28,第二个结果为 29。

更多详情请查看:https://wiki.php.net/rfc/rounding
goreyshi at gmail dot com
6 年前
当涉及到像美元这样的货币时,你需要在以下条件下显示它
- 所有数字都用两位小数表示美分。
- 用逗号隔开 1000。
- 对于超过两位小数的数字,四舍五入。

我使用 number_format 函数内的 round 函数来实现它

number_format((float)round( 625.371 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 625.37
number_format((float)round( 625.379 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 625.38
number_format((float)round( 1211.20 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 1,211.20
number_format((float)round( 625 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 625.00
feha at vision dot to
13 年前
这里有一个简短的函数来对分钟(小时)进行四舍五入...

<?php

function minutes_round ($hour = '14:03:32', $minutes = '5', $format = "H:i")
{
// by Femi Hasani [www.vision.to]
$seconds = strtotime($hour);
$rounded = round($seconds / ($minutes * 60)) * ($minutes * 60);
return
date($format, $rounded);
}

?>

你决定四舍五入到最接近的分钟...
例子将产生:14:05
omnibus at omnibus dot edu dot pl
13 年前
注意,如果数字为负数,并且精度大于小数点后的实际位数,则会出现奇怪的行为。

round(-0.07, 4);

返回

-0.07000000000000001

所以,如果你用要求小数点后最大位数的正则表达式验证它,你就会遇到麻烦。
Astro
4 年前
好的,我的函数的最终版本

function NumberPrecision($n, $precision=0, $is_round=true)
{
if ($is_round)
{
$r = 5 * pow(10, -($precision+1));
$n += (($n < 0) ? -$r : $r);
}

$comma = '.';

$r = 5 * pow(10, -($precision+2));
$n += (($n > 0) ? -$r : $r);
$n = number_format($n, $precision+1, $comma, '');

$n .= $comma;
list($n, $frac) = explode($comma, $n, 2);
$n = rtrim(rtrim($n, $comma) . $comma . substr($frac, 0, $precision), $comma);
return ($n);
}

在某些情况下,当内置函数如 round() 或 number_format() 返回意外结果时,它可能很有用。适用于正数和负数、零、像 1/12、0.3 这样的数字、科学记数法表示的数字等等。
terry at scribendi dot com
20 年前
要将任何数字四舍五入到给定的有效数字,使用 log10 来找出它的数量级

<?php round($n, ceil(0 - log10($n)) + $sigdigits); ?>

或者,当你需要显示一个每单位的价格,它可能少于几美分/便士/日元时,你可以使用

<?php
// $exp = 货币小数位数 - 日元/韩元为 0,大多数其他货币为 2
$dp = ceil(0 - log10($n)) + $sigdigits;
$display = number_format($amount, ($exp>$dp)?$exp:$dp);
?>

这始终显示至少货币要求的小数位数,但如果以精度显示单位价格需要更多位数,则会显示更多位数,例如:“英文校对,每字 0.0068 美元”,“英文啤酒,每品脱 6.80 美元”。
Anonymous
14 年前
此函数如果双精度或浮点数的值大于“$nb.5”,则返回 ceil($nb),否则返回 floor($nb)

<?php
function arounds_int($nb) {

if(!
is_numeric($nb)) {
return
false;
}

$sup = round($nb);
$inf = floor($nb);
$try = (double) $inf . '.5' ;

if(
$nb > $try) {
return
$sup;
}

return
$inf;
}
?>
Anonymous
6 年前
此函数具有奇怪的行为

<?php
echo round(0.045, 2); // 0.05
echo round(0.45, 1); // 0.5
echo round(1.045-1, 2); // 0.04 !!!
echo round(1.45-1, 1); // 0.5
Hayley Watson
4 年前
需要注意的是,此页面上称为“精度”的东西更准确地称为准确性;精度是指小数点两侧所有有效数字的总数,而准确性是指小数点右侧的数字。这是一个常见的混淆。
spectrumcat at gmail dot com
10 年前
如果有人需要“优雅”的四舍五入(更改其精度以获得非零值),以下是一个简单的函数

function gracefulRound($val, $min = 2, $max = 4) {
$result = round($val, $min);
if ($result == 0 && $min < $max) {
return gracefulRound($val, ++$min, $max);
} else {
return $result;
}
}

用法
$_ = array(0.5, 0.023, 0.008, 0.0007, 0.000079, 0.0000048);
foreach ($_ as $val) {
echo "{$val}: ".gracefulRound($val)."\n";
}

输出
0.5: 0.5
0.023: 0.02
0.008: 0.01
0.0007: 0.001
0.000079: 0.0001
0.0000048: 0
maxteiber at gmail dot com
17 年前
此函数的结果始终取决于底层的 C 函数。此函数存在许多编译器错误和浮点精度问题。现在,以下代码

<?php
echo round(141.075, 2);
?>

返回

141.07

在我的机器上。
所以,当你进行像会计这样的关键计算时,不要真正信任这个函数!
相反:只使用整数或使用字符串比较。
php at persignum dot com
9 年前
因为此函数缺少向上舍入和向下舍入常量,并且上面的说明没有真正告诉你如何向上或向下舍入到最接近的数字,以下是如何始终向上或始终向下舍入到最接近的数字的简单方法。

int 是你要舍入的数字

n 是你要舍入到的最接近的数字。

向上舍入到最接近的数字

function round_up($int, $n) {
return ceil($int / $n) * $n;
}

向下舍入到最接近的数字

function round_down(int, $n) {
return floor($int / $n) * $n;
}
lossantis at ig dot com dot br
14 年前
由于 PHP 5.3 开始提供像 PHP_ROUND_HALF_UP 这样的选项的 mode 参数,这里有一个用于向上取整的替代方案

<?php echo 252 / 40; // 6.3 ?>

如果我将它四舍五入

<?php echo round(252 / 40); // 6 ?>

你也可以使用向上取整(这可能对分页很有用)

<?php echo ceil(252/40); // 7 ?>

[由:[email protected] 编辑,以提高清晰度]
Bevan
14 年前
将数字格式化为指定的有效数字。

<?php
/**
* 将数字格式化为指定有效数字位数。
*
* @author Bevan Rudge, Drupal.geek.nz
*
* @param number $number
* 要格式化的数字。
* @param integer $sf
* 将数字四舍五入和格式化到的有效数字位数。
* @return string
* 四舍五入并格式化的数字。
*/
function format_number_significant_figures($number, $sf) {
// 我们四舍五入和格式化到多少小数位?
// @note 可能为负数。
$dp = floor($sf - log10(abs($number)));
// 将其作为普通数字四舍五入。
$number = round($number, $dp);
// 将格式化留给 format_number(),但始终将 0 格式化为 0 位小数。
return number_format($number, 0 == $number ? 0 : $dp);
}
?>
armanhakimsagar at gmail dot com
7 年前
$a = .9;

$b = .8;

$d = .1;

$e = .2;

$x = $a-$b;

$y = $e-$d;

$f = round($x,2);

echo $f;

if($f==$y){

echo "ok";
}
To Top