Примеры в разделах этой темы показывают различия между четырьмя настройками ProductMode
и SumMode
свойства:
FullPrecision
KeepLSB
KeepMSB
SpecifyPrecision
Чтобы следовать, сначала установите следующие настройки:
p = fipref; p.NumericTypeDisplay = 'short'; p.FimathDisplay = 'none'; p.LoggingMode = 'on'; F = fimath('OverflowAction','Wrap',... 'RoundingMethod','Floor',... 'CastBeforeSum',false); warning off format compact
Далее задайте fi
объекты a
и b
. Оба имеют подписи 8-битных типов данных. Длина дроби выбирается автоматически для каждого fi
цель для достижения наилучшей возможной точности:
a = fi(pi, true, 8)
a = 3.1563 s8,5
b = fi(exp(1), true, 8)
b = 2.7188 s8,5
Теперь задайте ProductMode
и SumMode
для a
и b
на FullPrecision
и посмотрите на некоторые результаты:
F.ProductMode = 'FullPrecision'; F.SumMode = 'FullPrecision'; a.fimath = F; b.fimath = F; a
a = 3.1563 %011.00101 s8,5
b
b = 2.7188 %010.10111 s8,5
a*b
ans = 8.5811 %001000.1001010011 s16,10
a+b
ans = 5.8750 %0101.11100 s9,5
В FullPrecision
mode, размер слова продукта увеличивается до суммы размеров слова операндов. В этом случае каждый операнд имеет 8 биты, поэтому размер слова продукта составляет 16 биты. Длина продукта дроби является суммой длин дробей операндов, в этом случае 5 + 5 = 10 биты.
Суммарный размер слова увеличивается на один самый значительный бит, чтобы учесть возможность бита переноса. Длина суммарной дроби совпадает с длинами дробей операндов, и все дробные биты сохраняются для полной точности. В этом случае обе операнды имеют 5 дробных биты, поэтому сумма имеет 5 дробных биты.
Теперь задайте ProductMode
и SumMode
для a
и b
на KeepLSB
и посмотрите на некоторые результаты:
F.ProductMode = 'KeepLSB'; F.ProductWordLength = 12; F.SumMode = 'KeepLSB'; F.SumWordLength = 12; a.fimath = F; b.fimath = F; a
a = 3.1563 %011.00101 s8,5
b
b = 2.7188 %010.10111 s8,5
a*b
ans = 0.5811 %00.1001010011 s12,10
a+b
ans = 5.8750 %0000101.11100 s12,5
В KeepLSB
режим, вы задаете размеры слова и наименее значимые биты результатов автоматически сохраняются. Этот режим моделирует поведение целочисленных операций в языке C.
Длина продукта дроби является суммой длин дробей операндов. В этом случае каждый операнд имеет 5
дробные биты, поэтому длина дроби продукта 10
биты. В этом режиме сохраняются все 10 дробных биты. Переполнение происходит, потому что для результата полной точности требуется 6
целочисленные биты и только 2
целочисленные биты остаются в продукте.
Длина суммарной дроби выравнивается с длинами дробей операндов, и в этой модели сохраняются все наименее значимые биты. В этом случае оба операнда имели 5
дробные биты, поэтому сумма 5
дробные биты. Полноточный результат требует 4
целочисленные биты и 7
целочисленные биты остаются в сумме, поэтому переполнение в сумме не происходит.
Теперь задайте ProductMode
и SumMode
для a
и b
на KeepMSB
и посмотрите на некоторые результаты:
F.ProductMode = 'KeepMSB'; F.ProductWordLength = 12; F.SumMode = 'KeepMSB'; F.SumWordLength = 12; a.fimath = F; b.fimath = F; a
a = 3.1563 %011.00101 s8,5
b
b = 2.7188 %010.10111 s8,5
a*b
ans = 8.5781 %001000.100101 s12,6
a+b
ans = 5.8750 %0101.11100000 s12,8
В KeepMSB
режим, вы задаете размеры слова и самые значительные биты суммы и результатов продукта автоматически сохраняются. Этот режим моделирует поведение многих устройств DSP, где продукт и сумма хранятся в реестрах двойной ширины, и программист выбирает передачу наиболее значимых битов из регистров в память после каждой операции.
Полноточный продукт требует 6
целочисленные биты и длина дроби продукта регулируются таким образом, чтобы соответствовать всем 6
целочисленные биты в этом режиме. Переполнение не происходит. Однако полноточный продукт требует 10
дробные биты и только 6
доступны. Поэтому точность теряется.
Полноточная сумма требует 4
целочисленные биты и длина дроби суммы корректируются таким образом, чтобы соответствовать всем 4
целочисленные биты в этом режиме. Полноточная сумма требует только 5
дробные биты; в этом случае существуют 8
, так что нет потери точности.
Этот пример показывает, что, в KeepMSB
mode изменяется длина дроби независимо от того, происходит ли переполнение. Длина дроби устанавливается на величину, необходимую для представления продукта в случае, если оба члена используют максимально возможное значение (18 + 18-16 = 20 в этом примере).
F = fimath('SumMode','KeepMSB','ProductMode','KeepMSB',... 'ProductWordLength',16,'SumWordLength',16); a = fi(100,1,16,-2,'fimath',F); a*a
ans = 0 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: -20 RoundingMethod: Nearest OverflowAction: Saturate ProductMode: KeepMSB ProductWordLength: 16 SumMode: KeepMSB SumWordLength: 16 CastBeforeSum: true
Теперь установите ProductMode
и SumMode
для a
и b
на SpecifyPrecision
и посмотрите на некоторые результаты:
F.ProductMode = 'SpecifyPrecision'; F.ProductWordLength = 8; F.ProductFractionLength = 7; F.SumMode = 'SpecifyPrecision'; F.SumWordLength = 8; F.SumFractionLength = 7; a.fimath = F; b.fimath = F; a
a = 3.1563 %011.00101 s8,5
b
b = 2.7188 %010.10111 s8,5
a*b
ans = 0.5781 %0.1001010 s8,7
a+b
ans = -0.1250 %1.1110000 s8,7
В SpecifyPrecision
необходимо задать как длину слова, так и длину дроби для сумм и продуктов. Этот пример неразумно использует дробные форматы для продуктов и сумм с 8
-бит размеров слова и 7
- биты.
Полноточный продукт требует 6
целочисленные биты и только пример задает 1
, поэтому продукт переполнен. Полноточный продукт требует 10
дробные биты, и только пример задает 7
, так что потеря точности в продукте.
Полноточная сумма требует 4
целочисленные биты и только пример задает 1
, поэтому сумма переполнена. Полноточная сумма требует 5
дробные биты, и пример задает 7
, так что нет потери точности в сумме.
Для получения дополнительной информации о fimath
объект и его свойства, см. «Свойства объекта fimath»