PHP整数与浮点数精度处理指南数字处理是编程中的基础操作。PHP的数字类型有整数和浮点数但刚上手的人经常被精度问题坑到。今天说说PHP数字的常见问题和解决方案。浮点数精度问题是所有编程语言都有的。0.1加0.2不等于0.3这个经典问题在PHP里也存在。php// 浮点数精度问题echo 0.1 0.2 . (0.1 0.2) . \n;echo 0.1 0.2 0.3: ;var_dump(0.1 0.2 0.3);// 正确的比较方式$sum 0.1 0.2;$epsilon 0.0001;echo 近似比较: ;var_dump(abs($sum - 0.3) $epsilon);// 使用roundecho round比较: ;var_dump(round($sum, 2) 0.3);// 货币计算用整数分function calculatePrice(float $price, int $quantity): int{// 把元转成分计算return (int)round($price * 100) * $quantity;}?BCMath扩展提供任意精度的数学运算php// BCMath 扩展if (!extension_loaded(bcmath)) {die(BCMath扩展未安装\n);}// 高精度加法$result bcadd(0.1, 0.2, 2);echo 0.1 0.2 $result\n;// 高精度比较echo bccomp: . bccomp(0.3, 0.3, 2) . \n; // 0表示相等echo bccomp: . bccomp(0.31, 0.3, 2) . \n; // 1表示大于// 常用BCMath函数$a 123.456;$b 78.91;echo 加法: . bcadd($a, $b, 4) . \n;echo 减法: . bcsub($a, $b, 4) . \n;echo 乘法: . bcmul($a, $b, 4) . \n;echo 除法: . bcdiv($a, $b, 4) . \n;echo 取模: . bcmod(100, 30) . \n;echo 乘方: . bcpow(2, 10) . \n;echo 开方: . bcsqrt(144, 2) . \n;// 货币计算class Money{private string $amount;private int $scale;public function __construct(string $amount, int $scale 2){$this-amount $amount;$this-scale $scale;}public function add(Money $other): Money{return new Money(bcadd($this-amount, $other-amount, $this-scale), $this-scale);}public function subtract(Money $other): Money{return new Money(bcsub($this-amount, $other-amount, $this-scale), $this-scale);}public function multiply(string $factor): Money{return new Money(bcmul($this-amount, $factor, $this-scale), $this-scale);}public function divide(string $divisor): Money{return new Money(bcdiv($this-amount, $divisor, $this-scale), $this-scale);}public function equals(Money $other): bool{return bccomp($this-amount, $other-amount, $this-scale) 0;}public function greaterThan(Money $other): bool{return bccomp($this-amount, $other-amount, $this-scale) 1;}public function __toString(): string{return number_format((float)$this-amount, $this-scale);}}$price new Money(99.99);$tax $price-multiply(0.13);$total $price-add($tax);echo 价格: $price\n;echo 税额: $tax\n;echo 总计: $total\n;?字符串转数字时的陷阱php// 隐式类型转换echo 123abc 10 . \n; // 133echo abc123 10 . \n; // 10echo 0x10 10 . \n; // 26 (十六进制)echo 010 10 . \n; // 20 (PHP 8不再支持八进制)// 安全的类型转换function safeInt(mixed $value, int $default 0): int{if (is_int($value)) return $value;if (is_string($value) preg_match(/^-?\d$/, $value)) {return (int)$value;}return $default;}function safeFloat(mixed $value, float $default 0.0): float{if (is_float($value)) return $value;if (is_string($value) preg_match(/^-?\d(\.\d)?$/, $value)) {return (float)$value;}return $default;}echo safeInt(123) . \n;echo safeInt(abc) . \n;echo safeInt(123abc) . \n;?PHP整数在32位和64位系统上的范围不同phpecho PHP_INT_MAX: . PHP_INT_MAX . \n;echo PHP_INT_MIN: . PHP_INT_MIN . \n;echo PHP_INT_SIZE: . PHP_INT_SIZE . 字节\n;// 大整数处理$large 12345678901234567890;if (PHP_INT_SIZE 8) {// 64位系统echo (int)$large . \n;} else {// 32位系统需要BCMathecho 大整数: . bcadd($large, 0, 0) . \n;}?round、ceil、floor的区别php$value 3.14159;echo round: . round($value, 2) . \n;echo round(PHP_ROUND_HALF_UP): . round(3.5, 0, PHP_ROUND_HALF_UP) . \n;echo round(PHP_ROUND_HALF_DOWN): . round(3.5, 0, PHP_ROUND_HALF_DOWN) . \n;echo ceil: . ceil($value) . \n;echo floor: . floor($value) . \n;// number_format$num 1234567.89;echo number_format: . number_format($num, 2) . \n;echo number_format(French): . number_format($num, 2, ,, ) . \n;?格式化数字和百分比phpclass NumFormatter{public static function formatNumber(float $value, int $decimals 2): string{return number_format($value, $decimals, ., ,);}public static function formatPercentage(float $value, int $decimals 1): string{return number_format($value * 100, $decimals) . %;}public static function formatCurrency(float $value, string $symbol ¥): string{return $symbol . number_format($value, 2, ., ,);}public static function formatBytes(int $bytes, int $precision 2): string{$units [B, KB, MB, GB, TB];$i 0;while ($bytes 1024 $i count($units) - 1) {$bytes / 1024;$i;}return round($bytes, $precision) . $units[$i];}public static function abbreviateNumber(float $value): string{if ($value 1000000000) return round($value / 1000000000, 1) . B;if ($value 1000000) return round($value / 1000000, 1) . M;if ($value 1000) return round($value / 1000, 1) . K;return (string)$value;}}echo NumFormatter::formatCurrency(1234567.89) . \n;echo NumFormatter::formatBytes(123456789) . \n;echo NumFormatter::abbreviateNumber(1523456) . \n;echo NumFormatter::formatPercentage(0.856) . \n;?PHP的数字处理需要注意浮点数精度、类型转换、大整数范围等问题。货币计算用BCMath扩展或整数分单位。比较浮点数用epsilon或round。掌握了这些数字处理就不会出问题了。
PHP整数与浮点数精度处理指南
发布时间:2026/6/3 11:43:13
PHP整数与浮点数精度处理指南数字处理是编程中的基础操作。PHP的数字类型有整数和浮点数但刚上手的人经常被精度问题坑到。今天说说PHP数字的常见问题和解决方案。浮点数精度问题是所有编程语言都有的。0.1加0.2不等于0.3这个经典问题在PHP里也存在。php// 浮点数精度问题echo 0.1 0.2 . (0.1 0.2) . \n;echo 0.1 0.2 0.3: ;var_dump(0.1 0.2 0.3);// 正确的比较方式$sum 0.1 0.2;$epsilon 0.0001;echo 近似比较: ;var_dump(abs($sum - 0.3) $epsilon);// 使用roundecho round比较: ;var_dump(round($sum, 2) 0.3);// 货币计算用整数分function calculatePrice(float $price, int $quantity): int{// 把元转成分计算return (int)round($price * 100) * $quantity;}?BCMath扩展提供任意精度的数学运算php// BCMath 扩展if (!extension_loaded(bcmath)) {die(BCMath扩展未安装\n);}// 高精度加法$result bcadd(0.1, 0.2, 2);echo 0.1 0.2 $result\n;// 高精度比较echo bccomp: . bccomp(0.3, 0.3, 2) . \n; // 0表示相等echo bccomp: . bccomp(0.31, 0.3, 2) . \n; // 1表示大于// 常用BCMath函数$a 123.456;$b 78.91;echo 加法: . bcadd($a, $b, 4) . \n;echo 减法: . bcsub($a, $b, 4) . \n;echo 乘法: . bcmul($a, $b, 4) . \n;echo 除法: . bcdiv($a, $b, 4) . \n;echo 取模: . bcmod(100, 30) . \n;echo 乘方: . bcpow(2, 10) . \n;echo 开方: . bcsqrt(144, 2) . \n;// 货币计算class Money{private string $amount;private int $scale;public function __construct(string $amount, int $scale 2){$this-amount $amount;$this-scale $scale;}public function add(Money $other): Money{return new Money(bcadd($this-amount, $other-amount, $this-scale), $this-scale);}public function subtract(Money $other): Money{return new Money(bcsub($this-amount, $other-amount, $this-scale), $this-scale);}public function multiply(string $factor): Money{return new Money(bcmul($this-amount, $factor, $this-scale), $this-scale);}public function divide(string $divisor): Money{return new Money(bcdiv($this-amount, $divisor, $this-scale), $this-scale);}public function equals(Money $other): bool{return bccomp($this-amount, $other-amount, $this-scale) 0;}public function greaterThan(Money $other): bool{return bccomp($this-amount, $other-amount, $this-scale) 1;}public function __toString(): string{return number_format((float)$this-amount, $this-scale);}}$price new Money(99.99);$tax $price-multiply(0.13);$total $price-add($tax);echo 价格: $price\n;echo 税额: $tax\n;echo 总计: $total\n;?字符串转数字时的陷阱php// 隐式类型转换echo 123abc 10 . \n; // 133echo abc123 10 . \n; // 10echo 0x10 10 . \n; // 26 (十六进制)echo 010 10 . \n; // 20 (PHP 8不再支持八进制)// 安全的类型转换function safeInt(mixed $value, int $default 0): int{if (is_int($value)) return $value;if (is_string($value) preg_match(/^-?\d$/, $value)) {return (int)$value;}return $default;}function safeFloat(mixed $value, float $default 0.0): float{if (is_float($value)) return $value;if (is_string($value) preg_match(/^-?\d(\.\d)?$/, $value)) {return (float)$value;}return $default;}echo safeInt(123) . \n;echo safeInt(abc) . \n;echo safeInt(123abc) . \n;?PHP整数在32位和64位系统上的范围不同phpecho PHP_INT_MAX: . PHP_INT_MAX . \n;echo PHP_INT_MIN: . PHP_INT_MIN . \n;echo PHP_INT_SIZE: . PHP_INT_SIZE . 字节\n;// 大整数处理$large 12345678901234567890;if (PHP_INT_SIZE 8) {// 64位系统echo (int)$large . \n;} else {// 32位系统需要BCMathecho 大整数: . bcadd($large, 0, 0) . \n;}?round、ceil、floor的区别php$value 3.14159;echo round: . round($value, 2) . \n;echo round(PHP_ROUND_HALF_UP): . round(3.5, 0, PHP_ROUND_HALF_UP) . \n;echo round(PHP_ROUND_HALF_DOWN): . round(3.5, 0, PHP_ROUND_HALF_DOWN) . \n;echo ceil: . ceil($value) . \n;echo floor: . floor($value) . \n;// number_format$num 1234567.89;echo number_format: . number_format($num, 2) . \n;echo number_format(French): . number_format($num, 2, ,, ) . \n;?格式化数字和百分比phpclass NumFormatter{public static function formatNumber(float $value, int $decimals 2): string{return number_format($value, $decimals, ., ,);}public static function formatPercentage(float $value, int $decimals 1): string{return number_format($value * 100, $decimals) . %;}public static function formatCurrency(float $value, string $symbol ¥): string{return $symbol . number_format($value, 2, ., ,);}public static function formatBytes(int $bytes, int $precision 2): string{$units [B, KB, MB, GB, TB];$i 0;while ($bytes 1024 $i count($units) - 1) {$bytes / 1024;$i;}return round($bytes, $precision) . $units[$i];}public static function abbreviateNumber(float $value): string{if ($value 1000000000) return round($value / 1000000000, 1) . B;if ($value 1000000) return round($value / 1000000, 1) . M;if ($value 1000) return round($value / 1000, 1) . K;return (string)$value;}}echo NumFormatter::formatCurrency(1234567.89) . \n;echo NumFormatter::formatBytes(123456789) . \n;echo NumFormatter::abbreviateNumber(1523456) . \n;echo NumFormatter::formatPercentage(0.856) . \n;?PHP的数字处理需要注意浮点数精度、类型转换、大整数范围等问题。货币计算用BCMath扩展或整数分单位。比较浮点数用epsilon或round。掌握了这些数字处理就不会出问题了。