Your PHP implementation appear to be using the common IEEE 754 64-bit binary format. In this format, finite values are represented, effectively, as a sign, an integer M less than 253, and an integer exponent e between −1074 and 971, inclusive. The value represented is +M•2e or −M•2e, according to the sign. (This format will often be described with M being a fraction between 1 and 2 with a certain number of bits after the radix point. The descriptions are mathematically equivalent, just useful for different purposes.)
Given this, we can easily see that the next representable number after 0 is +1•2−1074, which is approximately 4.94065645841246544•10−324.
In this format as stated, 1 can be represented as +1•20. However, to see what the smallest change that can be made to 1 is, we must normalize it by making M as large as possible. 1 can also be represented with M = 252 and e = −52, resulting in +252•2−52. In this form, we can see the next representable value greater than 1 is achieved by adding 1 to M, mkaing the number +(252+1)•2−52.
The difference between 1 and +(252+1)•2−52 is of course 1•2−52, which is exactly 2.220446049250313080847263336181640625•10−16.
Note that your code records $eTmp
(if $e
is not zero) after reducing $e
with $e = $e/2
, which means it reports the first value of $e
that does not cause a change. Thus it reports 1.11e-16 rather than 2.22e-16, which is the last value that does cause a change to 1.