if 语句中的变量赋值

Posted

技术标签:

【中文标题】if 语句中的变量赋值【英文标题】:Assignment of variable within if-statement 【发布时间】:2021-08-13 23:08:57 【问题描述】:

当我尝试在 if 语句的主体中分配变量 x 时,如果该变量也出现在 if 语句的条件下,我会得到意想不到的结果。

例如代码

model algorithmTest_25p05p2021


Real x(start=0);
Real y(start=0);

algorithm 

y := sin(time);
x := sin(time); 

if x < 0 then // replace with y < 0 --> x is correctly truncated
  x := 0;
end if;


end algorithmTest_25p05p2021;

导致

我在 OpenModelica 1.17.0 中使用了 OMEdit,仿真时间 120s,最大步进时间 1s。 我无法理解这里发生的事情。

在我的理解中,算法部分意味着x被初始化为其起始值0。初始化之后,我认为算法部分中的语句是按顺序执行的。因此,在 if 语句之前,x 被设置为 x=sin(time) 的值。 之后,我希望 if 语句在 sin(time) =0 时将 x 设置为 x=sin(time)。

您会看到发生了什么:在条件第一次触发后 x 保持为零。

更让我困惑的是,用“y

我在这里错过了什么?任何指向 Modelica 规范的指针?

编辑(27.05.2021): 由于这种行为似乎是 OpenModelica 1.17.0 中的一个错误,我将其发布在他们的 Github 上,请参阅 https://github.com/OpenModelica/OpenModelica/issues/7484

【问题讨论】:

这可能是一个错误。请注意,Modelica 中的算法很奇怪,关系触发事件,因此 x 是的,我希望 x 看起来像罪的积极部分。 “noEvent(x 我理解的情节正确吗? x 的值是否在 t=120s 时切换回正确的值?强烈表明我理解中的错误。似乎结束模拟的事件“修复”了那里的问题...... @MarkusA。 : 是的,你正确理解了情节。有趣的是,结束模拟的事件是否导致 x 跳到正确的值取决于我选择的模拟时间。 【参考方案1】:

这一定是一个错误。

显然x&lt;0 应该有一个事件,但事件逻辑仅在x 接近于零时才重要,因此对图形的影响应该很小。

我能找到的规范的相关部分是:

If 语句仅在为真时进行评估 https://specification.modelica.org/maint/3.5/statements-and-algorithm-sections.html#if-statement 如果条件和隐藏状态不一致,则会生成一个事件: https://specification.modelica.org/maint/3.5/equations.html#events-and-synchronization 从概念上讲,x 是用它的起始值初始化的,但这并不重要,因为它是无条件分配的 https://specification.modelica.org/maint/3.5/statements-and-algorithm-sections.html#execution-of-an-algorithm-in-a-model

【讨论】:

感谢您的帮助。您是否知道规避此错误的良好编码实践是什么?根据变量本身的值为变量赋值是一项常见的算法任务。我假设我总是可以在示例中使用像 y 这样的虚拟变量。您是否也知道其他 Modelica 环境(例如 Dymola)是否表现出相同的行为? Dymola 没有表现出这种行为,我希望其他工具也没有。我不知道如何规避它。

以上是关于if 语句中的变量赋值的主要内容,如果未能解决你的问题,请参考以下文章

在变量赋值powershell中执行if语句

PHP:在 IF 语句中为变量赋值

用SQL语句编写:定义两个变量并赋值,要求输出较小的那个值。

Python基础之变量赋值if语句

Freemarker变量赋值问题

PL/SQL流程控制