Выполните вычисления с фиксированной точкой

Вычисления с фиксированной точкой

Сложение и вычитание

Каждый раз, когда вы добавляете два числа фиксированной точки, вам, возможно, понадобится бит переноса, чтобы правильно представлять результат. Поэтому при добавлении двух чисел B-бита (с тем же масштабированием), получившееся значение имеет дополнительный бит по сравнению с этими двумя используемыми операндами.

a = fi(0.234375,0,4,6);
c = a+a
c = 

    0.4688

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 5
        FractionLength: 6
a.bin
ans =

1111
c.bin
ans =

11110

Если вы добавляете или вычитаете два числа с различной точностью, разделительная точка сначала должна быть выровнена, чтобы выполнить операцию. Результат состоит в том, что существует различие больше чем одного бита между результатом операции и операндами.

a = fi(pi,1,16,13);
b = fi(0.1,1,12,14);
c = a + b
c = 

    3.2416

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 18
        FractionLength: 14

Умножение

В целом продукт полной точности требует размера слова, равного сумме размера слова операндов. В следующем примере обратите внимание, что размер слова продукта c равен размеру слова a плюс размер слова b. Дробная длина c также равна дробной длине a плюс дробная длина b.

a = fi(pi,1,20), b = fi(exp(1),1,16)
a = 

    3.1416

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 20
        FractionLength: 17

b = 

    2.7183

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 13
c = a*b
c = 

    8.5397

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 36
        FractionLength: 30

Математика с другим созданным в типах данных

Обратите внимание на то, что в C, результат операции между целочисленным типом данных и двойным типом данных продвигает двойное. Однако в MATLAB®, результатом операции между встроенным целочисленным типом данных и двойным типом данных является целое число. В этом отношении объект fi ведет себя как встроенные целочисленные типы данных в MATLAB.

При выполнении сложения между fi и double, двойное брошено к fi с тем же numerictype как вход fi. Результатом операции является fi. При выполнении умножения между fi и double, двойное брошено к fi с тем же размером слова и со знаком из fi и лучшей длины части точности. Результатом операции является fi.

a = fi(pi);
a = 

    3.1416

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 13
b = 0.5 * a
b = 

    1.5708

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

При выполнении арифметики между fi и одним из встроенных целочисленных типов данных, [u]int[8, 16, 32], сохраняется размер слова и со знаком из целого числа. Результатом операции является fi.

a = fi(pi);
b = int8(2) * a
b = 

    6.2832

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 24
        FractionLength: 13

При выполнении арифметики между fi и логическим типом данных, логическое обработано как объект fi без знака со значением 0 или 1, и размер слова 1. Результатом операции является объект fi.

a = fi(pi);
b = logical(1);
c = a*b
c = 

    3.1416

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 17
        FractionLength: 13

Объект fimath

Свойства fimath задают правила для выполнения арифметических операций на объектах fi, включая математику, округление и свойства переполнения. Объект fi может иметь локальный объект fimath, или он может использовать свойства fimath по умолчанию. Можно присоединить объект fimath к объекту fi при помощи setfimath. Также можно задать свойства fimath в конструкторе fi при создании. Когда объект fi имеет локальный fimath, вместо того, чтобы использовать свойства по умолчанию, отображение объекта fi показывает свойства fimath. В этом примере a задали свойство ProductMode в конструкторе.

 a = fi(5,1,16,4,'ProductMode','KeepMSB')
a = 

     5

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

        RoundingMethod: Nearest
        OverflowAction: Saturate
           ProductMode: KeepMSB
     ProductWordLength: 32
               SumMode: FullPrecision
Свойство ProductMode a установлено в KeepMSB, в то время как остающиеся свойства fimath используют значения по умолчанию.

Примечание

Для получения дополнительной информации об объекте fimath его свойства и их значения по умолчанию, видят fimath Свойства объектов.

Рост разрядности

Следующая таблица показывает рост разрядности объектов fi, A и B, когда их свойства SumMode и ProductMode используют значение fimath по умолчанию, FullPrecision.

 ABСуммируйте = A+BПодталкивайте = A*B
Форматfi(vA,s1,w1,f1)fi(vB,s2,w2,f2)
Знакs1s2Ssum = (s1 || s2)Sproduct = (s1 || s2)
Целочисленные битыI1 = w1-f1-s1I2= w2-f2-s2Isum = max(w1-f1, w2-f2) + 1 - SsumIproduct = (w1 + w2) - (f1 + f2)
Дробные битыf1f2Fsum = max(f1, f2) Fproduct = f1 + f2
Общие битыw1w2Ssum + Isum + Fsumw1 + w2

Этот пример показывает, как рост разрядности может произойти в for - цикл.

T.acc = fi([],1,32,0);
T.x = fi([],1,16,0);

x = cast(1:3,'like',T.x);
acc = zeros(1,1,'like',T.acc);

for n = 1:length(x)
    acc = acc + x(n)
end
acc = 

     1
      s33,0

acc = 

     3
      s34,0

acc = 

     6
      s35,0
Размер слова acc увеличивается с каждой итерацией цикла. Это увеличение вызывает две проблемы: Каждый - та генерация кода, не позволяет изменять типы данных в цикле. Другой то, что, если цикл достаточно длинен, у вас заканчивается память в MATLAB. Смотрите Рост разрядности Управления для некоторых стратегий избежать этой проблемы.

Управление ростом разрядности

Используя fimath

Путем определения свойств fimath объекта fi можно управлять ростом разрядности, когда операции выполняются на объекте.

F = fimath('SumMode', 'SpecifyPrecision', 'SumWordLength', 8,...
 'SumFractionLength', 0);
a = fi(8,1,8,0, F);
b = fi(3, 1, 8, 0);
c = a+b
c = 

    11

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 8
        FractionLength: 0

        RoundingMethod: Nearest
        OverflowAction: Saturate
           ProductMode: FullPrecision
               SumMode: SpecifyPrecision
         SumWordLength: 8
     SumFractionLength: 0
         CastBeforeSum: true

Объект fi a имеет локальный объект fimath F. F задает размер слова и дробную длину суммы. При настройках fimath по умолчанию вывод, c, обычно имеет размер слова 9, и дробная длина 0. Однако, потому что a имел локальный объект fimath, получившийся объект fi имеет размер слова 8 и дробная длина 0.

Можно также использовать свойства fimath для роста бита управления в for - цикл.

F = fimath('SumMode', 'SpecifyPrecision','SumWordLength',32,...
'SumFractionLength',0);
T.acc = fi([],1,32,0,F);
T.x = fi([],1,16,0);

x = cast(1:3,'like',T.x);
acc = zeros(1,1,'like',T.acc);

for n = 1:length(x)
    acc = acc + x(n)
end
acc = 

     1
      s32,0

acc = 

     3
      s32,0

acc = 

     6
      s32,0

В отличие от этого того, когда T.acc использовал свойства fimath по умолчанию, рост разрядности acc теперь ограничивается. Таким образом размер слова acc остается в 32.

Преобразованное в нижний индекс присвоение

Иначе к биту управления рост при помощи преобразованного в нижний индекс присвоения. a(I) = b присваивает значения b в элементы a, заданного нижним вектором, I, при сохранении numerictype a.

T.acc = fi([],1,32,0);
T.x = fi([],1,16,0);

x = cast(1:3,'like',T.x);
acc = zeros(1,1,'like',T.acc);

% Assign in to acc without changing its type
for n = 1:length(x)
    acc(:) = acc + x(n)
end

acc (:) = acc + x (n) диктует что значения в нижнем векторе, (:), изменении. Однако numerictype вывода acc остается то же самое. Поскольку acc является скаляром, вы также получаете тот же вывод, если вы используете (1) в качестве нижнего вектора.

  for n = 1:numel(x)
    acc(1) = acc + x(n);
  end
acc = 

     1
      s32,0

acc = 

     3
      s32,0

acc = 

     6
      s32,0

numerictype acc остается то же самое в каждой итерации for - цикл.

Преобразованное в нижний индекс присвоение может также помочь вам рост бита управления в функции. В функции, cumulative_sum, не изменяется numerictype y, но значения в элементах, указанных n, делают.

function y = cumulative_sum(x)
% CUMULATIVE_SUM Cumulative sum of elements of a vector.
%
%   For vectors, Y = cumulative_sum(X) is a vector containing the
%   cumulative sum of the elements of X.  The type of Y is the type of X.
    y = zeros(size(x),'like',x);
    y(1) = x(1);
    for n = 2:length(x)
        y(n) = y(n-1) + x(n);
    end
end
y = cumulative_sum(fi([1:10],1,8,0))
y = 

     1     3     6    10    15    21    28    36    45    55

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 8
        FractionLength: 0

Примечание

Для получения дополнительной информации о преобразованном в нижний индекс присвоении смотрите, что subsasgn функционирует.

accumpos и accumneg

Иначе вы можете рост бита управления быть при помощи accumpos и функций accumneg, чтобы выполнить операции сложения и операции вычитания. Подобно использованию преобразованного в нижний индекс присвоения accumpos и accumneg сохраняют тип данных одного из его объектов входа fi, позволяя вам задать метод округления и действие переполнения во входных значениях.

Для получения дополнительной информации о том, как реализовать accumpos и accumneg, смотрите, Избегают Операций Многословных в Сгенерированном коде

Переполнение и округление

При выполнении вычислений с фиксированной точкой рассмотрите возможность и последствия переполнения. Объект fimath задает переполнение и округление режимов, используемых при выполнении арифметических операций.

Переполнение

Переполнение может произойти, когда результат операции превышает максимальное или минимальное представимое значение. Объект fimath имеет свойство OverflowAction, которое предлагает два способа иметь дело с переполнением: насыщение и переносится. Если вы устанавливаете OverflowAction на saturate, переполнение насыщается к максимальному или минимальному значению в области значений. Если вы устанавливаете OverflowAction на wrap, любое переполнение переносит использование арифметика по модулю, если без знака, или дополнительный перенос two, если подписано.

Для получения дополнительной информации о том, как обнаружить переполнение, смотрите Журналирование Потери значимости и Переполнения Используя fipref.

Округление

Существует несколько факторов, чтобы рассмотреть при выборе метода округления, включая стоимость, смещение, и существует ли возможность переполнения. Программное обеспечение Fixed-Point Designer™ предлагает несколько различных функций округления, чтобы удовлетворить требования вашего проекта.

Округление метода ОписаниеСтоимостьСмещениеВозможность переполнения
ceil Раунды к самому близкому представимому номеру в направлении положительной бесконечности.НизкоБольшой положительныйДа
convergentРаунды к самому близкому представимому номеру. В случае связи convergent округляется к самому близкому четному числу. Этот подход является наименее смещенным методом округления, предоставленным тулбоксом.ВысокоНесмещенныйДа
floorРаунды к самому близкому представимому номеру в направлении отрицательной бесконечности, эквивалентной дополнительному усечению two.НизкоБольшое отрицаниеНет
nearestРаунды к самому близкому представимому номеру. В случае связи nearest округляется к самому близкому представимому номеру в направлении положительной бесконечности. Этот метод округления является значением по умолчанию для создания объекта fi и арифметики fi.УмеренныйМаленький положительныйДа
roundРаунды к самому близкому представимому номеру. В случае связи, раундов метода round:
  • Положительные числа к самому близкому представимому номеру в направлении положительной бесконечности.

  • Отрицательные числа к самому близкому представимому номеру в направлении отрицательной бесконечности.

Высоко
  • Маленькое отрицание для отрицательных выборок

  • Несмещенный для выборок с равномерно распределенными положительными и отрицательными величинами

  • Маленький положительный для положительных выборок

Да
fixРаунды к самому близкому представимому номеру в направлении нуля.Низко
  • Большой положительный для отрицательных выборок

  • Несмещенный для выборок с равномерно распределенными положительными и отрицательными величинами

  • Большое отрицание для положительных выборок

Нет