Matlab : how to perform fixed-point arithmetic without expanding underlying data type?

StackOverflow https://stackoverflow.com/questions/19002666

  •  29-06-2022
  •  | 
  •  

Question

Google is silent on this issue. I'm currently implementing a numerical calculator on only 16-bit signed fixed point in Matlab. But arithmetic operation on 16bit fixed point causes expanding data type to the following

>> a = int16(1.5 * 4)
a = 6
>> T = numerictype(1, 16, 2)

T = DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 2
>> dis = reinterpretcast(a, T)

dis = 1.5000

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 2
>> c = dis * dis

c = 2.2500

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 32
        FractionLength: 4

i wish the variable c stays in WordLength 16, FractionLength 2. Is it possible that arithmetic operation on 16bit fixed point is done without expanding underlying data type? I'm going to take the risk of any overflow and underflow. Any help would be awesome.

EDIT : typing fimath into command window cause error. Why does this error occur?

>> F = fimath('OverflowAction','Wrap', 'RoundingMethod', 'Floor', ...
           'ProductWordLength', 16, 'ProductFractionLength', 2);
No public field OverflowAction exists for class embedded.fimath.

Error in fimath (line 72)
  this.(varargin{k}) = varargin{k+1};
Était-ce utile?

La solution

Local solution: You can use an fimath object to specify the precision of the result of a product:

F = fimath('OverflowMode','Wrap', 'RoundMode', 'Floor', ...
           'ProductMode', 'SpecifyPrecision', ...
           'ProductWordLength', 16, 'ProductFractionLength', 2);
dis.fimath = F;

Then the result will be:

>> dis*dis
ans =
         2.25

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 2

             RoundMode: floor
          OverflowMode: wrap
           ProductMode: SpecifyPrecision
     ProductWordLength: 16
 ProductFractionLength: 2
               SumMode: FullPrecision
      MaxSumWordLength: 128

Global solution: Alternatively, if you want this to apply to all your fixedpoint variables you can use

globalfimath('OverflowMode','Wrap', 'RoundMode', 'Floor', ...
             'ProductMode', 'SpecifyPrecision', ...
             'ProductWordLength', 16, 'ProductFractionLength', 2);

Note that to limit to 16 bit you need to specify the precision for sum as well (using SumMode and SumWordLength properties of fimath) otherwise the sum will have a word length of 17:

>> dis+dis
ans =
     3

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 17
        FractionLength: 2
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top