Short answer:
This is caused by round-off error. In this particular case, using a value slightly greater than 2 (such as 2.0001) for the last element of the list gives some margin for round-off error and solves the problem.
... \foreach \x in {1,1.1,...,2.0001} ... 
Detailed explanation:
Some numbers have an infinite binary expansion, i.e. their fractional part contains an infinitely repeating pattern. For instance,
0.1 (in decimal form)
corresponds to
0.0001100110011001100110011... (in binary form)
with the pattern 0011 repeating "forever" after the binary point.
Since both fixed-point and floating-point numbers only allocate a limited number of bits for the fractional part of a given number, they cannot store that infinite expansion and some rounding has to occur. TeX, as does PGFmath (I assume), uses a 32-bit fixed-point number representation system, where:
- 1 bit is used to flag an overflow,
- 1 bit is used to code for sign,
- 14 bits are used for the integral part of the number,
- 16 bits are used for the fractional part of the number.
It follows that
\pm 2^14-2^{-16} \approx \pm 16383.99999 are the largest and smallest representable numbers (respectively) of the system ; anything larger than that in magnitude corresponds to an overflow. However, that doesn't mean that all numbers in between are representable; some of them must be approximated by the number representation system.
I'm not sure what the rounding rule is in TeX but it seems that the number gets
- rounded up if the 17th bit after the binary point is 1,
- truncated if the 17th bit after the binary point is 0,
In the case of 0.1, the 17th bit after the binary point is 1; therefore, 0.1 gets rounded up to the next machine number i.e.
0.0001100110011010 (in binary form)
(Compare to the exact value of 0.1 written above).
In summary, the number manipulated by TeX is not 0.1 but a number slightly bigger than that. Therefore, the increment in \foreach \x in {1,1.1,...,2} is slightly larger than 0.1 and the final value visited is (approximately) 1.9 instead of 2.
Conversely
0.2 (in decimal form)
corresponds to
0.001100110011001100110011... (in binary form)
with the pattern 0011 repeating "forever" after the binary point. The 17th bit after the binary point is 0; therefore, 0.2 gets truncated/rounded down to the preceding machine number i.e.
0.001100110011011 (in binary form)
(Compare to the exact value of 0.2 written above).
In summary, the number manipulated by TeX is not 0.2 but a number slightly smaller than that. Therefore, the increment in \foreach \x in {1,1.2,...,2} is slightly smaller than 0.2 and the final value visited is (approximately) 2, as expected.
References:
- For more details on arithmetic in TeX: http://www.tug.org/TUGboat/tb28-3/tb90beebe.pdf
- Sections 61-62 of the TikZ/PGF manual