Back in February 2009 I posted about how to test for NaN in Simulink. The approach I talked about was more of a logical experiment based on the special properties of NaN than an ideal software solution. In Simulink R2009b the Relational Operator block got an upgrade to include isNaN. Let’s see how it works.
Relational Operator Block Upgrade
The Relational Operator is often used to compare signals and test for greater than (>), equals (==), and more. In R2009b it has the following new single input modes: isNaN, isFinite, and isInf.
These functions are familiar to those who program in MATLAB and they work the same way. When the input signal has the properties we are testing for, the block outputs true.
How does it work?
I talked to my colleague Omar who upgraded the block and he shared with me some key points. He mentioned that the block handles:
- real and complex signals
- any data type supported by Simulink including fixed point types
- endianness of your platform
These new operators are only meaningful with data types that can represent Inf and NaN. So how does it work with non-floating point types? If you pass in an integer, or a fixed-point type that cannot represent NaN of Inf, the block returns false. This is a key point for workflows where you might find yourself switching the data types in your design. This often happens when selecting proper fixed-point data type properties. If you are running simulations to gather ideal double precision results, you may need to handle Inf and NaN. When converting the model to fixed-point for implementation, the algorithm does not require any modifications.
The code generated for the isNaN function looks like this:
34 /* Outport: ‘<Root>/Out1’
35 * Inport: ‘<Root>/In1’
36 * RelationalOperator: ‘<Root>/Relational Operator’
38 isNaNCode_Y.Out1 = rtIsNaN(isNaNCode_U.In1);
The function rtIsNaN is part of rt_nonfinite.c:
61 /* Test if value is not a number */
62 boolean_T rtIsNaN(real_T value)
65 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
67 /* For MSVC 6.0, use a compiler specific comparison function */
68 return _isnan(value)? 1U:0U;
72 return((value!=value) ? 1U : 0U);
Further Optimization using Target Function Library
If your embedded target environment has a special function for handling tests for NaN, Inf or Finiteness you can use the Target Function Library to replace the call to rtIsNaN with that call.
What do you think?
Will you use the isInf, isNaN and isFinite mode of this block? Leave a comment here to tell me how.
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.