在第 902 页的手册中说
通常,当遇到列表项...时,它之前应该已经有两个列表项,即数字。
数字的例子有 1、-10 或 -0.24。我们把这些数字称为 x 和 y,设
d:=y−x
它们是差。接下来,三个点后面还应该有一个数字,我们把这个数字称为z
。在这种情况下,列表阅读的部分
x,y,...,z
被替换为x
,,,,,...,其中最后的点是语义点,而不是句法点。值 m 是满足以下条件的最大数:或x+d
满足以下条件:x+2d
x+3d
x+md
x+md≤z
d is positive
x+md ≥ z
d is negative
也许最好通过一些例子来解释这一点:以下<list>具有相同的效果:
\foreach \x in {0,0.1,...,0.5} {\x, }
0
收益率0.1
,,,,,0.20001
0.30002
0.40002
正如这里x=0
,我们推断2d=0.20001
,因此只有d=0.100005
。
编辑: 3d=0.30002
因此d=0.10000666666...
编辑:那么,在这种情况下,从条目0
中减去,并修改0.1
该条目。由于根本没有减去任何内容,这怎么可能呢?这是否意味着减法会从数字中减去某些内容?0.1
0.1
0
0.1
- 是不是因为 2 进制中的二进制减法用
TeX
? 用pgffor
? TeX?
是因为中的数字 0 的二进制编码吗pgffor
?- 如何
pgffor
计算 foreach 循环中的增量?
使用 www.DeepL.com/Translator 翻译
答案1
是如何\foreach \x in { a, b, ..., z } { <code> }
工作的?
基本上,PGF 确实
\start=a pt
\step=b pt
\advance\step by -\start
此处a
,b
和z
应为十进制数,\start
和\step
为dimen寄存器(不是真实名称)。然后,如手册所述,执行<code>
具有\start
初始值的;然后\advance\start by \step
执行并<code>
跟进。循环一直持续到\start>z pt
(此时<code>
不会执行)。这是\step>0pt
,但情况\step<0pt
类似。
现在,在 TeX 中如何使用 dimen 寄存器进行算术运算?
一个 dimen 寄存器的值以点为单位显示,但实际上以“缩放点”为单位存储,其中一个点是 65536 个缩放点。
在您的例子中,\step
设置为 0.1pt,相当于 6554sp。再加 0.1pt 使内部值变为 13108sp。当 13108sp 转换回点时,该值为 0.20001pt。
但是,\dimen0=0.2pt
对应于内部值 13107sp,因为 65536 乘以 2 等于 131072。并且0.00001pt
是 1sp,即最小非零 TeX 维度。
随着进一步的增加,舍入误差会累积。
应尽可能避免使用\foreach
小数值;当值为整数时,不会进行舍入。
答案2
0.1
二进制有无限的表示形式。例如,为什么浮点数中不存在 0.1?因此会有舍入误差。此外,正如@DavidCarlisle 在评论中指出的那样,TeX 擅长整数运算,这又增加了一层误差。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=16]
\foreach \x in {0,0.1,...,0.5}
\node at (\x,0.1) {\x};
\draw (0,0.05) -- (0.5,0.05);
\foreach \x[evaluate=\x as \y using \x/10] in {0,1,...,5}
\node at (\y,0) {\y};
\draw (0,-0.05) -- (0.5,-0.05);
\foreach \x[evaluate=\x as \y using \x/10] in {0,1,...,5}
\node at (\y,-0.1) {\pgfmathprintnumber[fixed,precision=1]{\y}};
\end{tikzpicture}
\end{document}
添加:的二进制表示 0.1
为
0.00011001100110011...(重复 0011)
如果计算机使用 16 个二进制小数存储上述内容,则将变成
0.0001100110011010
转换回3277/32768 = 0.100006103515625
。然后您将得到0.20001220703125
,0.300018310546875
和0.4000244140625
。这里不涉及减法。这只是计算机存储数字的方式。
第二次编辑: 正如 @egreg 指出的那样,TeX 中的实际“浮点运算”是通过维度寄存器实现的。因此,您将受到将 pt
转换为 时产生的舍入误差的影响sp
。
巧合的是,由于3277/32768 = 6554/65536
,这符合完美与我上面说明的转换:0.1
通过 0.5
正在积累恰恰如0.100006103515625
、0.20001220703125
、0.300018310546875
、0.4000244140625
和0.500030517578125
。