非整型数值变量使用时需要注意的问题
问题说明:
在仿真程序运行过程中,不可避免的出现非整型的数据 (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” 配合使用。