rem + $other->rem; $carry = intdiv($rem, self::MILLION); if ($this->micro > PHP_INT_MAX - $other->micro - $carry) { throw new \OverflowException('The amount is too large to add exactly.'); } return new self($this->micro + $other->micro + $carry, $rem % self::MILLION); } public function isZero(): bool { return $this->micro === 0 && $this->rem === 0; } /** The amount as a decimal string with $decimals places (0 to 6), rounded half up. */ public function toDecimalString(int $decimals): string { $decimals = max(0, min(6, $decimals)); $scale = 10 ** (6 - $decimals); $q = $scale === 1 ? $this->micro + ($this->rem >= 500_000 ? 1 : 0) : intdiv($this->micro + intdiv($scale, 2), $scale); if ($decimals === 0) { return (string) $q; } $digits = str_pad((string) $q, $decimals + 1, '0', STR_PAD_LEFT); return substr($digits, 0, -$decimals) . '.' . substr($digits, -$decimals); } }