问题说明:

在仿真程序运行过程中,不可避免的出现非整型的数据 (real, time等变量类型)。在数学计算中这种数据没有问题,但是由于程序中数据有效位数的限制,经常会出现错误运算出现极小的偏差的情况。这种问题在数据计算时几乎没有影响 ,但是在进行数据比较的时候,往往会出现意外的结果。这种问题在任何语言中应该是普遍存在的,但在仿真中这个问题极容易被忽视,导致严重的bug。

问题再现:

在SimTalk中Time型的变量在调试时仅显示小数点后4位,但是实际数据精度更高。这就导致了有时看似相同的时间,在比较时出现了不等的结果的情况。

如上图所示,Time1和Time2在调试界面中显示的时间相同,但是如果直接比较就会出现不同的结果。而在实际模型运行中,两个时间很有可能是相同的,只是计算时由于有效位数的问题,出现了0.0000000001的计算偏差,就出现了这种问题。

real型数据同理也会出现相同的问题。

解决方法:

在非整型数据时,不要直接利用 “=”, “>”, “<“, “>=”, “<=” 直接比较,需要考虑有效位数的问题。

Time型变量建议利用 “time_to_num” 函数转换为real型数据进行处理。比较方法如下:(以real型数据为例,两个变量为num1, num2)

方法1:

相等:abs(num1 – num2) < 0.0001   //小于一个极小值,具体数值可以根据数据精度确定

小于:num1 – num2 < -0.0001   // num1 小于 num2

大于:num1 – num2 > 0.0001  // num1 大于 num2

方法2:

相等:round(num1, 4) = round(num2, 4)   //保留有效数字位数根据数据精度确定

小于:round(num1, 4) < round(num2, 4)

大于:round(num1, 4) > round(num2, 4)

方法3:(仅在SimTalk 1.0 中可用,SimTalk 2.0 不可用)

相等:num1 == num2  // “==” 为约等于

小于等于:num1 <== num2  // “<==” 为约小于等于

大于等于:num1 >== num2  // “>==” 为约大于等于

注:约等于在使用之前要先定义精度,需要与函数 “setEpsilon” 配合使用。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注