我运行了代码
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\int_new:N\l_rand
\int_step_inline:nn{50}{
\int_set:Nn\l_rand{\int_rand:n{56}}
\int_show:n{\l_rand+(\l_rand-1)/(8-1)}
}
\end{document}
使用 xetex。在我的日志中显示
> \l_rand +(\l_rand -1)/(8-1)=64.
<recently read> }
这很荒谬。显然 56+(56-1)/(8-1)=63,而且不可能再大了,所以这64
是一个错误计算。事实上 55/7 接近 8,所以这可能是由于浮点计算错误造成的。
那么我怎样才能让 tex 避免这样的错误呢?
答案1
比较
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\int_eval:n { 1/2 } \par
\int_eval:n { 55/7 } \par
\int_eval:n { \int_div_truncate:nn { 55 } { 7 } }
\ExplSyntaxOff
\end{document}
这将打印
1
8
7
因为/
四舍五入到下一个整数(四舍五入到远离零的位置)。对于对称性也有\int_div_round:nn
,但\int_div_round:nn { 55 } { 7 }
与 相同55/7
。
手册中记录了这一点,我们对此无能为力,因为/
根据 e-TeX 实现,这就是整数表达式中所做的。
这是否是一个好的选择还有待商榷,但改变这种行为是不可能的,因为 e-TeX 已经这样大约 25 年了,而一个改变会破坏大量文档。
即使使用也\fp_eval:n
无法解决问题,因为你需要
\fp_eval:n { trunc(55/7,0) }
无论如何(以牺牲速度为代价)。