浮動小数点数の操作
Nette\Utils\Floatsは、浮動小数点数を比較するための便利な関数を含む静的クラスです。
インストール:
composer require nette/utils
すべての例では、エイリアスが作成されていることを前提としています。
use Nette\Utils\Floats;
動機
なぜ浮動小数点数を比較するためのクラスが必要なのか、疑問に思うかもしれません。演算子<
、>
、===
を使用すれば十分ではないでしょうか。
それは完全には正しくありません。次のコードは何を出力すると思いますか?
$a = 0.1 + 0.2;
$b = 0.3;
echo $a === $b ? 'same' : 'not same';
コードを実行すると、プログラムがnot same
を出力することに驚く人もいるでしょう。
浮動小数点数を使用した数学演算では、10進数と2進数の間の変換によりエラーが発生します。たとえば、0.1 + 0.2
は0.300000000000000044…
になります。したがって、比較する際には、特定の小数点以下のわずかな差を許容する必要があります。
そして、それがまさにクラスFloats
が行うことです。次の比較は、期待どおりに機能します。
echo Floats::areEqual($a, $b) ? 'same' : 'not same'; // same
NAN
を比較しようとすると、例外\LogicException
がスローされます。
クラスFloats
は、1e-10
未満の差を許容します。より高い精度で作業する必要がある場合は、代わりにBCMathライブラリを使用してください。
浮動小数点数の比較
areEqual (float $a, float $b): bool
$a
= $b
の場合にtrue
を返します。
Floats::areEqual(10, 10.0); // true
isLessThan (float $a, float $b): bool
$a
< $b
の場合にtrue
を返します。
Floats::isLessThan(9.5, 10.2); // true
Floats::isLessThan(INF, 10.2); // false
isLessThanOrEqualTo (float $a, float $b): bool
$a
<= $b
の場合にtrue
を返します。
Floats::isLessThanOrEqualTo(9.5, 10.2); // true
Floats::isLessThanOrEqualTo(10.25, 10.25); // true
isGreaterThan (float $a, float $b): bool
$a
> $b
の場合にtrue
を返します。
Floats::isGreaterThan(9.5, -10.2); // true
Floats::isGreaterThan(9.5, 10.2); // false
isGreaterThanOrEqualTo (float $a, float $b): bool
$a
>= $b
の場合にtrue
を返します。
Floats::isGreaterThanOrEqualTo(9.5, 10.2); // false
Floats::isGreaterThanOrEqualTo(10.2, 10.2); // true
compare (float $a, float $b): int
$a
<
$b
の場合は-1
を返し、等しい場合は0
を返し、$a
>
$b
の場合は1
を返します。
たとえば、関数usort
で使用できます。
$arr = [1, 5, 2, -3.5];
usort($arr, [Float::class, 'compare']);
// $arr は [-3.5, 1, 2, 5] になります
ヘルパー関数
isZero (float $value): bool
値がゼロに等しい場合にtrue
を返します。
Floats::isZero(0.0); // true
Floats::isZero(0); // true
isInteger (float $value): bool
値が整数の場合にtrue
を返します。
Floats::isInteger(0); // true
Floats::isInteger(0.0); // true
Floats::isInteger(-5.0); // true
Floats::isInteger(-5.1); // false
Floats::isInteger(INF); // false
Floats::isInteger(NAN); // false