PHP大整数与高精度数学计算
PHP的整数在32位系统上是32位,64位系统上是64位。超出范围的数据需要BCMath扩展处理。今天说说高精度计算。
PHP_INT_MAX和PHP_INT_MIN限制了整数的范围。
```php
echo "PHP_INT_MAX: " . PHP_INT_MAX . "\n";
echo "PHP_INT_SIZE: " . PHP_INT_SIZE . " 字节\n";
?>
BCMath扩展提供任意精度计算。
```php
if (!extension_loaded('bcmath')) die("BCMath未安装\n");
$a = '12345678901234567890';
$b = '98765432109876543210';
echo "加法: " . bcadd($a, $b, 0) . "\n";
echo "减法: " . bcsub($a, $b, 0) . "\n";
echo "乘法: " . bcmul($a, $b, 0) . "\n";
echo "除法: " . bcdiv($a, $b, 10) . "\n";
echo "取模: " . bcmod($a, '1234567890') . "\n";
echo "乘方: " . bcpow('2', '100') . "\n";
echo "比较: " . bccomp($a, $b) . "\n";
?>
货币计算专用类。
```php
class Money
{
private string $amount;
public function __construct(string $amount)
{
$this->amount = $amount;
}
public static function fromDecimal(string $value): self
{
$parts = explode('.', $value, 2);
$fraction = str_pad(substr($parts[1] ?? '00', 0, 2), 2, '0');
return new self($parts[0] . $fraction);
}
public function toDecimal(): string
{
$len = strlen($this->amount);
if ($len <= 2) return '0.' . str_pad($this->amount, 2, '0', STR_PAD_LEFT);
return substr($this->amount, 0, $len - 2) . '.' . substr($this->amount, $len - 2);
}
public function add(Money $other): self
{
return new self(bcadd($this->amount, $other->amount, 0));
}
public function subtract(Money $other): self
{
return new self(bcsub($this->amount, $other->amount, 0));
}
public function multiply(float $factor): self
{
return new self(bcmul($this->amount, (string)$factor, 0));
}
public function compare(Money $other): int
{
return bccomp($this->amount, $other->amount, 0);
}
public function __toString(): string
{
return $this->toDecimal();
}
}
$price = Money::fromDecimal('99.99');
$tax = $price->multiply(0.13);
$total = $price->add($tax);
echo "价格: $price\n";
echo "税额: $tax\n";
echo "总计: $total\n";
?>
浮点数精度问题。
```php
echo "0.1 + 0.2 = " . (0.1 + 0.2) . "\n";
var_dump(0.1 + 0.2 == 0.3);
var_dump(round(0.1 + 0.2, 2) == 0.3);
// BCMath
echo bcadd('0.1', '0.2', 2) . "\n";
?>
格式化数字。
```php
$num = 1234567.89;
echo number_format($num, 2) . "\n";
echo number_format($num, 2, ',', ' ') . "\n";
echo round(3.14159, 2) . "\n";
echo ceil(3.14) . "\n";
echo floor(3.14) . "\n";
?>
字符串安全的类型转换。
```php
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;
}
?>
PHP的数字处理需要注意精度问题。货币计算用BCMath扩展或整数分单位。浮点数比较用epsilon。理解这些能避免很多数字相关的bug。
PHP大整数与高精度数学计算