-
-
Notifications
You must be signed in to change notification settings - Fork 282
/
floats.texy
149 lines (95 loc) · 3.75 KB
/
floats.texy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
Schwebekörper-Funktionen
************************
.[perex]
[api:Nette\Utils\Floats] ist eine statische Klasse mit nützlichen Funktionen zum Vergleich von Fließkommazahlen.
Installation:
```shell
composer require nette/utils
```
Alle Beispiele gehen davon aus, dass der folgende Klassenalias definiert ist:
```php
use Nette\Utils\Floats;
```
Motivation .[#toc-motivation]
=============================
Sie fragen sich, wozu eine Float-Vergleichsklasse gut ist? Sie können die Operatoren `<`, `>`, `===`, denken Sie.
Das ist nicht ganz richtig. Was, glauben Sie, wird dieser Code ausgeben?
```php
$a = 0.1 + 0.2;
$b = 0.3;
echo $a === $b ? 'same' : 'not same';
```
Wenn Sie den Code ausführen, werden einige von Ihnen überrascht sein, dass das Programm `not same` ausgibt.
Bei mathematischen Operationen mit Fließkommazahlen treten aufgrund der Umrechnung zwischen Dezimal- und Binärsystem Fehler auf. Zum Beispiel entspricht `0.1 + 0.2` `0.300000000000000044…` . Daher müssen wir beim Vergleich von Fließkommazahlen eine kleine Differenz ab einer bestimmten Dezimalstelle tolerieren.
Und genau das tut die Klasse `Floats`. Der folgende Vergleich wird wie erwartet funktionieren:
```php
echo Floats::areEqual($a, $b) ? 'gleich' : 'nicht gleich'; // gleich
```
Beim Versuch, `NAN` zu vergleichen, kommt es zu einer `\LogicException` Ausnahme.
.[tip]
Die Klasse `Floats` toleriert Unterschiede, die kleiner sind als `1e-10`. Wenn Sie mit größerer Genauigkeit arbeiten müssen, verwenden Sie stattdessen die BCMath-Bibliothek.
Float-Vergleich .[#toc-float-comparison]
========================================
areEqual(float $a, float $b): bool .[method]
--------------------------------------------
Gibt `true` zurück, wenn `$a` = `$b`.
```php
Floats::areEqual(10, 10.0); // true
```
isLessThan(float $a, float $b): bool .[method]
----------------------------------------------
Gibt `true` zurück, wenn `$a` < `$b`.
```php
Floats::isLessThan(9.5, 10.2); // true
Floats::isLessThan(INF, 10.2); // false
```
isLessThanOrEqualTo(float $a, float $b): bool .[method]
-------------------------------------------------------
Gibt `true` zurück, wenn `$a` <= `$b`.
```php
Floats::isLessThanOrEqualTo(9.5, 10.2); // true
Floats::isLessThanOrEqualTo(10.25, 10.25); // true
```
isGreaterThan(float $a, float $b): bool .[method]
-------------------------------------------------
Gibt `true` zurück, wenn `$a` > `$b`.
```php
Floats::isGreaterThan(9.5, -10.2); // true
Floats::isGreaterThan(9.5, 10.2); // false
```
isGreaterThanOrEqualTo(float $a, float $b): bool .[method]
----------------------------------------------------------
Gibt `true` zurück, wenn `$a` >= `$b`.
```php
Floats::isGreaterThanOrEqualTo(9.5, 10.2); // false
Floats::isGreaterThanOrEqualTo(10.2, 10.2); // true
```
compare(float $a, float $b): int .[method]
------------------------------------------
Wenn `$a` < `$b` ist, wird `-1` zurückgegeben, wenn sie gleich sind, wird `0` and if `$a` > `$b` zurückgegeben und `1`.
Sie kann z. B. mit der Funktion `usort` verwendet werden.
```php
$arr = [1, 5, 2, -3.5];
usort($arr, [Float::class, 'compare']);
// $arr ist [-3.5, 1, 2, 5]
```
Helfer-Funktionen .[#toc-helpers-functions]
===========================================
isZero(float $value): bool .[method]
------------------------------------
Gibt `true` zurück, wenn der Wert Null ist.
```php
Floats::isZero(0.0); // true
Floats::isZero(0); // true
```
isInteger(float $value): bool .[method]
---------------------------------------
Gibt `true` zurück, wenn der Wert eine ganze Zahl ist.
```php
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
```