Matlab: как выполнять арифметику с фиксированной точкой без расширения базового типа данных?

Гугл молчит по этому поводу. В настоящее время я реализую числовой калькулятор только с 16-битной фиксированной точкой со знаком в Matlab. Но арифметическая операция с 16-битной фиксированной точкой приводит к расширению типа данных до следующего

>> 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

я хочу, чтобы переменная c оставалась в WordLength 16, FractionLength 2. Возможно ли, чтобы арифметическая операция с 16-битной фиксированной точкой выполнялась без расширения базового типа данных? Я собираюсь взять на себя риск любого переполнения и недополнения. Любая помощь будет потрясающей.

EDIT: ввод fimath в командном окне вызывает ошибку. Почему возникает эта ошибка?

>> 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};

person inherithandle    schedule 25.09.2013    source источник


Ответы (1)


Локальное решение: вы можете использовать объект fimath для указания точности результата продукта:

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

Тогда результат будет:

>> 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

Глобальное решение: в качестве альтернативы, если вы хотите, чтобы это применялось ко всем вашим переменным с фиксированной точкой, вы можете использовать

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

Обратите внимание, что для ограничения до 16 бит вам также необходимо указать точность для суммы (используя свойства SumMode и SumWordLength для fimath), иначе сумма будет иметь длину слова 17:

>> dis+dis
ans =
     3

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 17
        FractionLength: 2
person Mohsen Nosratinia    schedule 25.09.2013
comment
@inherithandle Исправлено! - person Mohsen Nosratinia; 25.09.2013