为什么“时间== 0.5”不是Modelica语言中的离散表达式?

问题描述

我建立了一个简单的模型来理解“离散表达式”的概念,下面是代码

model Trywhen
  parameter Real B[ :] =   {1.0,2.0,3.0};
algorithm 
    when time>=0.5 then
      Modelica.Utilities.Streams.print("message");
    end when;
  annotation (uses(Modelica(version="3.2.3")));
end Trywhen;

但是在检查模型时,出现错误,表明“ time == 0.5”不是离散表达式。

enter image description here

enter image description here

如果我将time==0.5更改为time>=0.5,则模型将通过检查。

enter image description here

如果我使用if-clausewhen-clause,则该模型可以正常工作,但是会显示警告消息,“无法比较Real类型的变量是否相等”。

enter image description here

我的问题是:

  1. 为什么time==0.5不是离散表达式?
  2. 为什么不能比较Real类型的变量是否相等?比较两个Real类型的变量时,这似乎很常见。

解决方法

第一个问题并不重要,因为不允许使用time==0.5

第二个问题很重要: 在其他语言中,比较实数是否相等是常见的问题,也是常见的错误来源-除非特别注意。

仅在某些处理器(例如Intel)上混合使用80位和64位浮点数(或带来性能损失),并且仅仅在处理器上使用浮点比较是一个非常糟糕的主意。在其他情况下,它可能无法按预期工作。在这种情况下,可以将0.5表示为浮点数,但不能将0.1和0.2表示为浮点数。

通常abs(x-y)<eps是一个很好的选择,但它取决于预期的用途,而eps取决于其他因素。不仅要提高机器精度,还要使用哪种算法来计算x和y及其误差传播。

在Modelica中,该问题比在许多其他语言中更为严重,因为允许工具对表达式进行更多的优化(包括符号操作),这使得为eps找出一个好的价值更加困难。

所有这些问题意味着我们决定不允许进行平等比较-并要求更适当的选择。

特别是,如果您知道只会从一个方向实现平等,则可以避免许多问题。在这种情况下,time会增加,因此如果在某个事件中它>0.5不会在以后的事件中<=0.5出现,而when只会在第一次触发该表达式变为真。

因此,when time>=0.5仅触发一次,并且大约在time == 0.5时触发,因此它是一个很好的选择。但是,可能存在一些数字误差,因此可能会在0.500000000000001处触发。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...