算术运算符
算术运算符是 PHP 中最基本的运算符,用于执行数学计算。PHP 支持标准的加、减、乘、除运算,以及取模、求幂和类型标识等运算。
基础概念
PHP 的算术运算符与基础数学运算一致。支持二元运算(两个操作数)和一元运算(一个操作数)。
算术运算符列表
| 运算符 | 名称 | 结果 | 示例 |
|---|---|---|---|
+$a | 标识(一元加) | 将 $a 转为 int 或 float | +$a |
-$a | 取反(一元减) | $a 的负值 | -$a |
$a + $b | 加法 | $a 和 $b 的和 | 5 + 3 = 8 |
$a - $b | 减法 | $a 和 $b 的差 | 10 - 4 = 6 |
$a * $b | 乘法 | $a 和 $b 的积 | 3 * 7 = 21 |
$a / $b | 除法 | $a 除以 $b 的商 | 15 / 3 = 5 |
$a % $b | 取模 | $a 除以 $b 的余数 | 10 % 3 = 1 |
$a ** $b | 求幂 | $a 的 $b 次方 | 2 ** 10 = 1024 |
加减乘除
基本算术运算
php
<?php
declare(strict_types=1);
// 加法
$sum = 10 + 20;
echo "10 + 20 = {$sum}\n"; // 30
// 减法
$diff = 50 - 18;
echo "50 - 18 = {$diff}\n"; // 32
// 乘法
$product = 6 * 7;
echo "6 * 7 = {$product}\n"; // 42
// 除法
$quotient = 15 / 3;
echo "15 / 3 = {$quotient}\n"; // 5
// 除法的结果类型
echo gettype(15 / 3) . "\n"; // integer(整除返回 int)
echo gettype(15 / 4) . "\n"; // double(非整除返回 float)除法的返回类型规则
除法类型规则
/ 运算符始终返回 float,除非两个操作数都是 int(或可转换为 int 的数字字符串)且能整除,此时返回 int。
php
<?php
declare(strict_types=1);
// 整除:两个 int 且能整除,返回 int
var_dump(10 / 2); // int(5)
var_dump(100 / 10); // int(10)
// 非整除:返回 float
var_dump(10 / 3); // float(3.333...)
var_dump(7 / 2); // float(3.5)
// 有浮点数参与:返回 float
var_dump(10.0 / 2); // float(5)
var_dump(10 / 2.0); // float(5)
// 整数除法函数(PHP 7+)
echo intdiv(10, 3) . "\n"; // 3(截断小数部分)
echo intdiv(-10, 3) . "\n"; // -3(向零截断)
echo intdiv(10, -3) . "\n"; // -3(向零截断)整数溢出
php
<?php
declare(strict_types=1);
// PHP_INT_MAX 加 1 会自动转为 float
$large = PHP_INT_MAX;
echo $large . "\n"; // 9223372036854775807(64位系统)
echo gettype($large) . "\n"; // integer
$overflow = $large + 1;
echo $overflow . "\n"; // 9.2233720368548E+18
echo gettype($overflow) . "\n"; // double取模运算符
基本用法
php
<?php
declare(strict_types=1);
// 基本取模
echo 5 % 3 . "\n"; // 2
echo 10 % 3 . "\n"; // 1
echo 12 % 4 . "\n"; // 0
// 取模运算符的操作数会先转为 int
echo 5.7 % 3.2 . "\n"; // 2(5 % 3)
echo -5 % 3 . "\n"; // -2(结果与被除数同号)
echo 5 % -3 . "\n"; // 2(结果与被除数同号)
echo -5 % -3 . "\n"; // -2(结果与被除数同号)取模结果的符号
取模 $a % $b 的结果符号与 $a(被除数)相同,而与 $b(除数)无关。
浮点数取模
% 运算符的操作数会先转换为整数,不能用于真正的浮点数取模。使用 fmod() 函数处理浮点数取模:
php
<?php
declare(strict_types=1);
// % 会将操作数转为 int
echo 5.5 % 2.2 . "\n"; // 1((int)5.5 % (int)2.2 = 5 % 2 = 1)
// fmod() 保留浮点精度
echo fmod(5.5, 2.2) . "\n"; // 1.1
echo fmod(7.5, 2.0) . "\n"; // 1.5
echo fmod(-5.5, 2.2) . "\n"; // -1.1(与被除数同号)求幂运算符
** 运算符(PHP 5.6+)
php
<?php
declare(strict_types=1);
// 基本求幂
echo 2 ** 10 . "\n"; // 1024
echo 3 ** 4 . "\n"; // 81
echo 10 ** 0 . "\n"; // 1(任何数的0次方)
echo 2 ** -1 . "\n"; // 0.5(负指数返回浮点数)
// 右结合性
echo 2 ** 3 ** 2 . "\n"; // 512(从右到左:2 ** (3 ** 2) = 2 ** 9 = 512)
// 等价于 pow() 函数
echo pow(2, 10) . "\n"; // 1024求幂优先级
** 的优先级高于乘除取模,但低于一元运算:
php
<?php
declare(strict_types=1);
// ** 优先级高于 *
echo 2 * 3 ** 2 . "\n"; // 18(先 3**2=9,再 2*9=18)
// 等价于
echo 2 * (3 ** 2) . "\n"; // 18
// 一元减优先级高于 **
echo -2 ** 2 . "\n"; // 4(先 (-2)**2 = 4)
echo (-2) ** 2 . "\n"; // 4(用括号明确)
echo -(2 ** 2) . "\n"; // -4(先 2**2=4,再取负)详细说明
一元加和一元减
php
<?php
declare(strict_types=1);
// 一元加:将值转换为 int 或 float
$val = +"42";
echo gettype($val) . "\n"; // integer
$val2 = +"3.14";
echo gettype($val2) . "\n"; // double
// 一元减:取负值
$positive = 42;
$negative = -$positive;
echo $negative . "\n"; // -42
$negative2 = -(-$positive);
echo $negative2 . "\n"; // 42字符串递增/递减
PHP 支持对字母字符进行递增运算:
php
<?php
declare(strict_types=1);
// 字母递增
$a = "Z";
$a++;
echo $a . "\n"; // AA
$b = "Az";
$b++;
echo $b . "\n"; // Ba
$c = "z9";
$c++;
echo $c . "\n"; // aa0
// 字符递减(仅限字母)
$d = "B";
$d--;
echo $d . "\n"; // A(A 不能再递减)
// 递减不适用于多位字母
$e = "AA";
// $e--; // 不会产生预期结果字符递增的限制
字符递增仅支持纯字母字符(a-z、A-Z)。不能递减超过 "A" 或 "a"。字符串中的数字会被单独处理。
组合赋值运算符
php
<?php
declare(strict_types=1);
$a = 10;
$a += 5; // 等价于 $a = $a + 5,$a = 15
echo $a . "\n";
$a -= 3; // $a = $a - 3 = 12
echo $a . "\n";
$a *= 2; // $a = $a * 2 = 24
echo $a . "\n";
$a /= 4; // $a = $a / 4 = 6
echo $a . "\n";
$a %= 4; // $a = $a % 4 = 2
echo $a . "\n";
$a **= 3; // $a = $a ** 3 = 8(PHP 5.6+)
echo $a . "\n";实战示例
数学计算函数
php
<?php
declare(strict_types=1);
/**
* 计算圆的面积和周长
*/
function calculateCircle(float $radius): array
{
$area = M_PI * $radius ** 2;
$circumference = 2 * M_PI * $radius;
return [
"area" => round($area, 2),
"circumference" => round($circumference, 2),
"diameter" => $radius * 2,
];
}
$result = calculateCircle(5.0);
echo "Area: {$result["area"]}\n"; // Area: 78.54
echo "Circumference: {$result["circumference"]}\n"; // Circumference: 31.42
echo "Diameter: {$result["diameter"]}\n"; // Diameter: 10分页计算
php
<?php
declare(strict_types=1);
/**
* 计算分页信息
*/
function calculatePagination(int $totalItems, int $perPage, int $currentPage): array
{
$totalPages = (int)ceil($totalItems / $perPage);
$currentPage = max(1, min($currentPage, $totalPages));
$offset = ($currentPage - 1) * $perPage;
return [
"total_items" => $totalItems,
"per_page" => $perPage,
"current_page" => $currentPage,
"total_pages" => $totalPages,
"offset" => $offset,
"has_prev" => $currentPage > 1,
"has_next" => $currentPage < $totalPages,
];
}
$pagination = calculatePagination(105, 20, 3);
echo "Total: {$pagination["total_items"]}\n";
echo "Pages: {$pagination["total_pages"]}\n";
echo "Current: {$pagination["current_page"]}\n";
echo "Offset: {$pagination["offset"]}\n";
echo "Has prev: " . ($pagination["has_prev"] ? "Yes" : "No") . "\n";
echo "Has next: " . ($pagination["has_next"] ? "Yes" : "No") . "\n";单位换算
php
<?php
declare(strict_types=1);
/**
* 文件大小格式化
*/
function formatFileSize(int $bytes): string
{
$units = ["B", "KB", "MB", "GB", "TB"];
for ($i = 0; $bytes >= 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, 2) . " " . $units[$i];
}
echo formatFileSize(1024) . "\n"; // 1 KB
echo formatFileSize(1048576) . "\n"; // 1 MB
echo formatFileSize(5242880) . "\n"; // 5 MB
echo formatFileSize(1073741824) . "\n"; // 1 GB注意事项
1. 浮点数精度问题
php
<?php
declare(strict_types=1);
// 浮点数精度问题
echo 0.1 + 0.2 . "\n"; // 0.3(看似正确)
echo (0.1 + 0.2) === 0.3 ? "true" : "false"; // false
// 比较:使用 epsilon
$a = 0.1 + 0.2;
$b = 0.3;
$epsilon = 0.00001;
echo (abs($a - $b) < $epsilon) ? "equal" : "not equal"; // equal
// 或使用 BC Math 扩展
// echo bcadd("0.1", "0.2", 10); // "0.3000000000"2. 除零错误
php
<?php
declare(strict_types=1);
// 整数除零
// echo 10 / 0; // DivisionByZeroError
// 浮点数除零(返回 INF 或 NAN)
echo 10.0 / 0 . "\n"; // INF(无限大)
echo 0.0 / 0.0 . "\n"; // NAN(非数字)
// 安全检查
function safeDivide(float $a, float $b): ?float
{
if (abs($b) < 1e-10) {
return null;
}
return $a / $b;
}
echo safeDivide(10, 3) . "\n"; // 3.333...
var_dump(safeDivide(10, 0)); // null3. 取模运算的限制
php
<?php
declare(strict_types=1);
// 取模运算符只接受整数
// echo 10.5 % 3.2; // 先转为 int:10 % 3 = 1
// 对 0 取模会导致错误(PHP 8+)
// echo 10 % 0; // DivisionByZeroError
// 安全的取模
function safeMod(int $a, int $b): ?int
{
if ($b === 0) {
return null;
}
return $a % $b;
}
echo safeMod(10, 3) . "\n"; // 1
var_dump(safeMod(10, 0)); // null最佳实践
- 使用
intdiv()做整数除法:明确需要整数结果时 - 注意浮点数精度:比较浮点数使用 epsilon
- 安全处理除零:始终检查除数不为零
- 使用
fmod()处理浮点取模:%会截断为整数 - 格式化输出时使用
round():控制小数位数 - 大数运算使用 BC Math:涉及金额时使用
bcmath扩展 - 使用
M_PI等预定义常量:避免手写圆周率等
下一节
算术运算符是最基础的运算符。接下来将学习比较运算符、逻辑运算符、赋值运算符等其他 PHP 运算符。请根据目录继续学习其他运算符章节。