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

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

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

Каждый раз, когда вы добавляете два числа фиксированной точки, вам, возможно, понадобится бит переноса, чтобы правильно представлять результат. Поэтому при добавлении двух чисел 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 объект FF задает размер слова и дробную длину суммы. Под 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Раунды к самому близкому представимому номеру в направлении нуля.Низко
  • Большой положительный для отрицательных выборок

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

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

Нет