exponenta event banner

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

Арифметика с фиксированной точкой

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

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

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 сохранить тип данных одного из его входных данных fi объекты, позволяя задать метод округления и действие переполнения во входных значениях.

Дополнительные сведения о внедрении accumpos и accumneg, см. раздел Избегание многословных операций в сгенерированном коде

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

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

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

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

Дополнительные сведения о том, как обнаружить переполнение, см. в разделе Запись переполнения и переполнения с помощью fipref.

Округление

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

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

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

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

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

  • Небольшой позитив для положительных проб

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

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

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

Нет