При добавлении двух чисел с фиксированной точкой может потребоваться бит переноса, чтобы правильно представить результат. По этой причине при сложении двух 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: 6a.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: 13c = 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: 13b = 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: 13fimath свойства определяют правила выполнения арифметических операций на 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: FullPrecisionProductMode имущество a имеет значение KeepMSB в то время как остальные fimath в свойствах используются значения по умолчанию.Примечание
Для получения дополнительной информации о fimath его свойства и значения по умолчанию см. в разделе Свойства объекта fimath.
В следующей таблице показан рост битов fi объекты, A и B, когда их SumMode и ProductMode свойства используют значение по умолчанию fimath значение, FullPrecision.
| A | B | Сумма = A + B | Компания = A * B | |
|---|---|---|---|---|
| Формат | fi(vA,s1,w1,f1) | fi(vB,s2,w2,f2) | — | — |
| Знак | s1 | s2 | Ssum = (s1||s2) | Sproduct = (s1||s2) |
| Целочисленные биты | I1 = w1-f1-s1 | I2= w2-f2-s2 | Isum = max(w1-f1, w2-f2) + 1 - Ssum | Iproduct = (w1 + w2) - (f1 + f2) |
| Дробные биты | f1 | f2 | Fsum = max(f1, f2) | Fproduct = f1 + f2 |
| Всего битов | w1 | w2 | Ssum + Isum + Fsum | w1 + 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,0acc увеличивается с каждой итерацией цикла. Это увеличение вызывает две проблемы: одна заключается в том, что генерация кода не позволяет изменять типы данных в цикле. Другая заключается в том, что если цикл достаточно длинный, то в MATLAB не хватает памяти. Некоторые стратегии, позволяющие избежать этой проблемы, см. в разделе Управление ростом битов.Путем указания 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 | Округляет до ближайшего представимого числа в направлении нуля. | Низко |
| Нет |