Why does fi signed plus unsigned produce needless range bits?

4 visualizzazioni (ultimi 30 giorni)
When adding signed and unsigned fi variables with the default full-precision settings, sometimes the output type has needless range bits. Why is that?
Consider the following example. The output type of the addition is numerictype(1,7,4), but the smaller type numerictype(1,6,4) with one less range bit is also full-precision.
fp = fipref;
fp.NumericTypeDisplay = 'short';
format compact
format short
nta = numerictype(0,4,4);
ntb = numerictype(1,4,3);
va = [
upperbound(nta);
lowerbound(nta);
];
vb = [
upperbound(ntb);
lowerbound(ntb);
];
y = va + vb
y =
1.8125 -1.0000 numerictype(1,7,4)
y.bin
ans = 2×7 char array
'0011101' '1110000'
nty_reduced = numerictype(1,6,4);
y_reduced = fi(y,nty_reduced)
y_reduced =
1.8125 -1.0000 numerictype(1,6,4)
y_reduced.bin
ans = 2×6 char array
'011101' '110000'

Risposta accettata

Andy Bartlett
Andy Bartlett il 21 Ott 2022
Modificato: Andy Bartlett il 21 Ott 2022
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.
% Weighted Bit Columns
% ---- ---- ---- ---- ---- ---- ----
% Real World 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4
% Value 4 2 1 .5 .25 .125
% ---- ---- ---- ---- ---- ---- ----
% numerictype(0,4,1) 7.5 = 1 1 1 1
% numerictype(1,4,4) 0.4375 = 0 1 1 1
%
% Same example using binary-point notation
%
% Type Real World Notation: Binary Point
% Value
% numerictype(0,4,1) 7.5 = 111.1
% numerictype(1,4,4) 0.4375 = .0111
%
fp = fipref;
fp.NumericTypeDisplay = 'short';
format compact
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
% Example
% MSB of signed is to the left of MSB of unsigned
%
% No bits overlap in bit weighting columns
%
% Type Real World Notation: Binary Point
% Value
% numerictype(0,4,4) 0.9375 = .1111
% numerictype(1,4,0) 7 = 0111.
nta = numerictype(0,4,4);
ntb = numerictype(1,4,0);
ntyTight = numerictype(1,8,4);
va = [
upperbound(nta);
lowerbound(nta);
];
vb = [
upperbound(ntb);
lowerbound(ntb);
];
y = va + vb
y =
7.9375 -8.0000 numerictype(1,10,4)
y.bin
ans = 2×10 char array
'0001111111' '1110000000'
yTight = fi(y,ntyTight)
yTight =
7.9375 -8.0000 numerictype(1,8,4)
yTight.bin
ans = 2×8 char array
'01111111' '10000000'
nty = numerictype(y);
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
% Example
% MSB of signed is to the left of MSB of unsigned
%
% Two bits overlap in bit weighting columns
%
% Type Real World Notation: Binary Point
% Value
% numerictype(0,4,4) 0.9375 = .1111
% numerictype(1,4,2) 1.75 = 01.11
nta = numerictype(0,4,4);
ntb = numerictype(1,4,2);
ntyTight = numerictype(1,7,4);
va = [
upperbound(nta);
lowerbound(nta);
];
vb = [
upperbound(ntb);
lowerbound(ntb);
];
y = va + vb
y =
2.6875 -2.0000 numerictype(1,8,4)
y.bin
ans = 2×8 char array
'00101011' '11100000'
yTight = fi(y,ntyTight)
yTight =
2.6875 -2.0000 numerictype(1,7,4)
yTight.bin
ans = 2×7 char array
'0101011' '1100000'
nty = numerictype(y);
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
% Example
% MSB of unsigned is to the left of MSB of signed
%
% One bit of overlap in bit weighting columns
%
% Type Real World Notation: Binary Point
% Value
% numerictype(0,4,0) 15 = 1111.
% numerictype(1,4,3) 0.875 = 0.111
nta = numerictype(0,4,0);
ntb = numerictype(1,4,3);
ntyTight = numerictype(1,8,3);
va = [
upperbound(nta);
lowerbound(nta);
];
vb = [
upperbound(ntb);
lowerbound(ntb);
];
y = va + vb
y =
15.8750 -1.0000 numerictype(1,9,3)
y.bin
ans = 2×9 char array
'001111111' '111111000'
yTight = fi(y,ntyTight)
yTight =
15.8750 -1.0000 numerictype(1,8,3)
yTight.bin
ans = 2×8 char array
'01111111' '11111000'
nty = numerictype(y);
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
% Example
% MSB of unsigned is to the left of MSB of signed
%
% Two bits overlap in bit weighting columns
%
% Type Real World Notation: Binary Point
% Value
% numerictype(0,4,0) 15 = 1111.
% numerictype(1,4,2) 1.75 = 01.11
nta = numerictype(0,4,0);
ntb = numerictype(1,4,2);
ntyTight = numerictype(1,8,2);
va = [
upperbound(nta);
lowerbound(nta);
];
vb = [
upperbound(ntb);
lowerbound(ntb);
];
y = va + vb
y =
16.7500 -2.0000 numerictype(1,8,2)
y.bin
ans = 2×8 char array
'01000011' '11111000'
yTight = fi(y,ntyTight)
yTight =
16.7500 -2.0000 numerictype(1,8,2)
yTight.bin
ans = 2×8 char array
'01000011' '11111000'
nty = numerictype(y);
fprintf('Output type %s\nTight type %s\n',nty.tostring,ntyTight.tostring);
Output type numerictype(1,8,2) Tight type numerictype(1,8,2)

Più risposte (0)

Tag

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by