Metapost 中奇怪的 mod 操作员行为

Metapost 中奇怪的 mod 操作员行为

我目前正面临 metapostmod操作员的一个奇怪行为。

以下是一段简单的代码:

\startMPcode
    for x = 0 step .5 until 10:
      if (x mod 1) = 0.5: label.top(x, (x*cm, 0cm)) ; fi
    endfor
\stopMPcode

产生以下结果

第一个结果

这正是我们所期望的。

现在让我们将步骤改为0.1

\startMPcode
    for x = 0 step .1 until 10:
      if (x mod 1) = 0.5: label.top(x, (x*cm, 0cm)) ; fi
    endfor
\stopMPcode

再试一次,我们得到以下结果

第二个结果

而不是上面的。

这里发生了什么?为什么结果不同?

答案1

正如评论中提到的,这是一个舍入错误。这个问题并非 MetaPost 独有,它出现在所有实现浮点运算的编程语言中。

一种解决方案是乘以十,然后使用round()函数进行整数舍入。为了防止标签中输出 0.00000n,您可以通过乘法、舍入然后除法来执行相同的技巧。

独立 MetaPost MWE:

prologues:=3;
beginfig(1);
for x = 0 step .1 until 10:
  if round((x mod 1) * 10) = 5: label.top(decimal(round(x * 10)/10), (x*cm, 0cm)) ; fi
endfor
endfig;
end

答案2

Metapost 中的非整数算术很特殊。

您可以尝试传递-numbersystem=decimal运行时选项。从代码中使用它

for x = 0 step .1 until 2:
  show (x mod 1) ;
endfor

我明白了

>> 0
>> 0.1
>> 0.2
>> 0.3
>> 0.4
>> 0.5
>> 0.6
>> 0.7
>> 0.8
>> 0.9
>> 0
>> 0.1
>> 0.2
>> 0.3
>> 0.4
>> 0.5
>> 0.6
>> 0.7
>> 0.8
>> 0.9
>> 0

或者,使用整数并在测试后缩放。

相关内容