【実務・中級編】HSLの数学関数とPHPの浮動小数点:型安全な数値計算の設計 – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

浮動小数点の悪夢を断ち切る:Hack型システムによる数値計算の厳格化

PHPのコードベースで最も「静かにシステムを殺す」原因は何か? それは、`float`の曖昧な精度と、型付けが甘い数値処理だ。

PHPの`0.1 + 0.2 === 0.3`が`false`を返すという事実は、もはや古典的なジョークですらない。これは設計上の欠陥であり、銀行システムや高精度な課金ロジックを扱う現場では致命的なバグの温床となる。

HHVMの深淵を知る者として断言しよう。「なんとなく動く」数値計算は、Hackでは許容されない。 HSL(Hack Standard Library)を活用し、型安全な境界線を構築する方法を伝授する。

—

1. なぜ「PHPの数値」は信頼できないのか

PHPの動的型付けは、暗黙の型変換(Type Juggling)を許容する。`”10.0″ + 5` が `15.0` になる世界では、IEEE 754浮動小数点数の「誤差」が、算術演算の連鎖によって増幅され、最終的に境界値条件(`if ($amount >= 100)`)を破壊する。

Hackでは、この不確実性を型システムで封じ込める。

2. HSLを活用した「型安全な数値」設計パターン

実務において、不特定多数の数値計算を行う際は、以下の原則を徹底せよ。

1. 入力のバリデーションを型変換と同時に行う
2. ビジネスロジック内では `float` を直接扱わない(可能なら `int` に正規化する)
3. HSLの `Math` モジュールを介して計算をカプセル化する

実装例:安全な価格計算ユニット

namespace App\Finance;

use HH\Lib\Math;

/

  • 浮動小数点の誤差を回避するため、最小単位(セントや銭)をintとして扱う。
  • クラスの内部状態をintで隠蔽することで、外部からの副作用を遮断する。

/
final class Money {
// 内部では常に整数(最小単位)で保持する
private int $amountInCents;

public function __construct(int $amountInCents) {
$this->amountInCents = $amountInCents;
}

public function add(Money $other): this {
return new self($this->amountInCents + $other->amountInCents);
}

/

  • 浮動小数点の計算が必要な場合のみ、計算の直前で変換し、
  • 即座に丸め処理を行う。

/
public function applyTax(float $taxRate): this {
// Math\round を明示的に使用し、精度を制御する
$taxed = (float)$this->amountInCents (1.0 + $taxRate);
return new self((int)Math\round($taxed));
}

public function toFloat(): float {
return (float)$this->amountInCents / 100.0;
}
}

3. なぜこの設計がプロダクションで生き残るのか

このコードの美しさは、「浮動小数点を保持させない」という制約にあります。

  • HHVMのJIT最適化: `int`はCPUのレジスタに直接ロード可能であり、浮動小数点演算ユニット(FPU)を無駄に占有しない。型が確定しているため、HHVMは型チェックのオーバーヘッドを排除し、最高速の機械語を出力する。
  • 型推論の明確化: `Money`型として扱うことで、開発者は「これは単なる数値ではなく、計算規則を伴う通貨である」という文脈を即座に理解できる。

4. プロダクションコードにおける「禁じ手」

レビューで即座にリジェクトすべきコードパターンを挙げておく。

  • `is_numeric()` に頼る: 型システムが崩壊している証拠。`string`から`float`へ安易にキャストして計算を行うと、将来的なリファクタリングで必ず死ぬ。
  • 比較演算子での浮動小数点比較: `if ($a == $b)` は絶対に使ってはならない。必ず `Math\abs($a – $b) < EPSILON` のような許容誤差(イプシロン)を定義した比較関数を経由すること。

結びに:型システムは「守り」ではない、「攻め」である

多くのエンジニアは型定義を「面倒な制約」と捉えるが、それは大きな誤解だ。型システムとは、「システムが絶対に破綻しない領域」をコンパイラに保証させる最強の防衛戦略である。

Hackの型チェッカーは、君たちが眠っている間も、深夜のデプロイの最中も、数学的な整合性を監視している。この力を信じ、数値をただの「器」としてではなく、厳格な「契約」として扱ってほしい。

次回のレビューでは、`float` がコードに登場した瞬間、「なぜこれを `int` で表現できないのか?」と問いかけてみてほしい。その瞬間から、君のコードベースは一段上の信頼性を獲得するはずだ。

タイトルとURLをコピーしました