MATLAB: Different values after rounding when using fixed point data types

fixedpointtyperoundingerrorssimulink

We found a certain behavior with the evaluation of the constant block.
1) in constant block is a value = 0.235 has data type U16_0_655D35000000000002_0_FFFF_L -Result-> 0.23
2) constant block with Parameter b has data type U16_0_655D35000000000002_0_FFFF_L , reslut = 0.23
b =
Parameter with properties:
Value: 0.2350
DataType: 'auto'
3) constant block with Parameter c has data type U16_0_655D35000000000002_0_FFFF_L , result = 0.24
c =
Parameter with properties:
Value: 0.2350
DataType: 'U16_0_655D35000000000002_0_FFFF_L'
could you please explain me difference between using Parameter and a value in constant block?

Best Answer

Since values 0.235 and slope 0.01 cannot be represented in power of two, these numbers cannot be represented accurately in the binary form. The compiler within the Simulink and MATLAB tries to fit the values between the number buckets. The value 0.235 falls between 0.23499999...9 and 0.23500000..001. The difference in the values is because of the way MATLAB and Simulink define this value in the binary form. The compiler has to break the tie between the two number buckets. The MATLAB breaks the tie towards 'inf' and Simulink breaks it towards '0'. This behavior is unpredictable and depends on the different computations performed on the value during the casting.
In MATLAB, the value gets quantized using slope value and gets directly converted to fixed point. Whereas, in Simulink, the value first gets quantized as double. That is the number (double value) gets represented in binary and then fixed point type casting happens. This brings in some precision losses.
We can turn on the checkbox "Use floating-point multiplication to handle net slope corrections" in Simulink to resolve this issue of non-power of two slope. The issue can be demostrated using fi objects:
>> f = fimath
f =
RoundingMethod: Nearest
OverflowAction: Saturate
ProductMode: FullPrecision
SumMode: FullPrecision
>> a = fi(0.2350,U16_0_655D35000000000002_0_FFFF_L, f)
a =
0.240000000000000
DataTypeMode: Fixed-point: slope and bias scaling
Signedness: Unsigned
WordLength: 16
Slope: 0.01
Bias: 0
RoundingMethod: Nearest
OverflowAction: Saturate
ProductMode: FullPrecision
SumMode: FullPrecision
f =
RoundingMethod: Floor
OverflowAction: Wrap
ProductMode: FullPrecision
SumMode: FullPrecision
>> a = fi(0.2350,U16_0_655D35000000000002_0_FFFF_L, f)
a =
0.230000000000000
DataTypeMode: Fixed-point: slope and bias scaling
Signedness: Unsigned
WordLength: 16
Slope: 0.01
Bias: 0
RoundingMethod: Floor
OverflowAction: Wrap
ProductMode: FullPrecision
SumMode: FullPrecision