The behavior observed when adding signed and unsigned inputs is currently a limitation in Fixed-Point Designer. The sum output does support full-precision output, but in some cases there may be 1 or 2 needless range bits. MathWorks plans to improve the behavior in a future release to provide a tight full-precision type for the output.
Assume
- one input is a signed fi object with binary-point scaling
- one input is an unsigned fi object with binary-point scaling
- both inputs are set to give SumMode = FullPrecision which is the default
The full-precision output type obtained from adding this signed and unsigned pair can have 0, 1, or 2 needless range bits. If it is 0, we call that tight.
The number of needless range bits if any depends on the relative location of the input bits when placed in weighting columns. One factor is how many of the input bits overlap. The other factor is which of the two most significant bits (MSB) is left of the other if any.
The following example shows the bits of two variables with different type aligned by their weights.
fp.NumericTypeDisplay = 'short';
The two types have one bit of overlap. That overlap is in the column with weight 0.5 which is the first bit to the right of the binary point.
The MSB of the unsigned type is in the column with weight 4 which is 3 bits to the left of the binary point. The MSB of the signed type is in the column with weight 0.5. The unsigned MSB is to the left of the signed MSB with regard to weighting columns.
The cases when the output has 2 needless range bits, 1 needless range bit, or is tight will be described by four examples. The headings of the example describe the general conditions under which that situation occurs.
Two Needless Bits, Signed MSB to left, no overlap
nta = numerictype(0,4,4);
ntb = numerictype(1,4,0);
ntyTight = numerictype(1,8,4);
y = va + vb
y =
7.9375
-8.0000
numerictype(1,10,4)
y.bin
ans =
'0001111111'
'1110000000'
yTight = fi(y,ntyTight)
yTight =
7.9375
-8.0000
numerictype(1,8,4)
yTight.bin
ans =
'01111111'
'10000000'
fprintf('Output type %s\nTight type %s\n',nty.tostring,ntyTight.tostring);
Output type numerictype(1,10,4)
Tight type numerictype(1,8,4)
One Needless Bit, Signed MSB to left, some overlap
nta = numerictype(0,4,4);
ntb = numerictype(1,4,2);
ntyTight = numerictype(1,7,4);
y = va + vb
y =
2.6875
-2.0000
numerictype(1,8,4)
y.bin
ans =
'00101011'
'11100000'
yTight = fi(y,ntyTight)
yTight =
2.6875
-2.0000
numerictype(1,7,4)
yTight.bin
ans =
'0101011'
'1100000'
fprintf('Output type %s\nTight type %s\n',nty.tostring,ntyTight.tostring);
Output type numerictype(1,8,4)
Tight type numerictype(1,7,4)
One Needless Bit, Unsigned MSB to left, overlap 1 or fewer bits
nta = numerictype(0,4,0);
ntb = numerictype(1,4,3);
ntyTight = numerictype(1,8,3);
y = va + vb
y =
15.8750
-1.0000
numerictype(1,9,3)
y.bin
ans =
'001111111'
'111111000'
yTight = fi(y,ntyTight)
yTight =
15.8750
-1.0000
numerictype(1,8,3)
yTight.bin
ans =
'01111111'
'11111000'
fprintf('Output type %s\nTight type %s\n',nty.tostring,ntyTight.tostring);
Output type numerictype(1,9,3)
Tight type numerictype(1,8,3)
Tight Output Type, all other binary-point cases
nta = numerictype(0,4,0);
ntb = numerictype(1,4,2);
ntyTight = numerictype(1,8,2);
y = va + vb
y =
16.7500
-2.0000
numerictype(1,8,2)
y.bin
ans =
'01000011'
'11111000'
yTight = fi(y,ntyTight)
yTight =
16.7500
-2.0000
numerictype(1,8,2)
yTight.bin
ans =
'01000011'
'11111000'
fprintf('Output type %s\nTight type %s\n',nty.tostring,ntyTight.tostring);
Output type numerictype(1,8,2)
Tight type numerictype(1,8,2)