Создание данных с фиксированной точкой

В этом примере показаны основы использования числового объекта с фиксированной точкой fi.

Обозначение

Числовой объект с фиксированной точкой называется fi потому что Джей Х. Уилкинсон использовал fi для обозначения расчетов с фиксированной точкой в его классических текстах «Округление Ошибок в алгебраических процессах» (1963) и «Алгебраическое Собственное значение задача» (1965).

Setup

В этом примере могут использоваться параметры отображения или настройки, отличающиеся от используемых в данный момент. Чтобы гарантировать, что текущие настройки и настройки отображения не будут изменены при запуске этого примера, пример автоматически сохраняет и восстанавливает их. Следующий код захватывает текущие состояния для любых настроек или свойств отображения, которые изменяются в примере.

originalFormat = get(0, 'format');
format loose
format long g
% Capture the current state of and reset the fi display and logging
% preferences to the factory settings.
fiprefAtStartOfThisExample = get(fipref);
reset(fipref);

Атрибуты фиксированной точки по умолчанию

Чтобы назначить тип данных с фиксированной точкой числу или переменной с параметрами с фиксированной точкой по умолчанию, используйте fi конструктор. Получившееся значение с фиксированной точкой называется a fi объект.

Для примера следующее создает fi объекты a и b с атрибутами, показанными на отображении, все из которых мы можем задать, когда переменные будут построены. Обратите внимание, что когда FractionLength свойство не задано, оно автоматически устанавливается на «лучшую точность» для заданного размера слова, сохраняя наиболее значимые биты значения. Когда WordLength свойство не задано, оно по умолчанию равняется 16 битам.

a = fi(pi)
a = 

              3.1416015625

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 13
b = fi(0.1)
b = 

        0.0999984741210938

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

Задание свойств Signed и WordLength

Второй и третий числовые аргументы задают Signed (true или 1 = signed, false или 0 = unsigned), и WordLength в битах, соответственно.

% Signed 8-bit
a = fi(pi, 1, 8)
a = 

                   3.15625

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

The sfi конструктор может также использоваться, чтобы создать fi со знаком объект

a1 = sfi(pi,8)
a1 = 

                   3.15625

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 8
        FractionLength: 5
% Unsigned 20-bit
b = fi(exp(1), 0, 20)
b = 

          2.71828079223633

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 20
        FractionLength: 18

The ufi конструктор может использоваться, чтобы создать беззнаковое fi объект

b1 = ufi(exp(1), 20)
b1 = 

          2.71828079223633

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 20
        FractionLength: 18

Точность

Данные хранятся внутри с такой точностью, как задано. Однако важно знать, что инициализация переменных с высокой точностью с фиксированной точностью с переменными с двойной точностью с плавающей точностью может не дать вам разрешение, которое вы можете ожидать на первый взгляд. Например, давайте инициализируем беззнаковую 100-битную переменную с фиксированной точкой с 0,1, а затем рассмотрим ее двоичное расширение:

a = ufi(0.1, 100);
bin(a)
ans =

    '1100110011001100110011001100110011001100110011001101000000000000000000000000000000000000000000000000'

Обратите внимание, что бесконечное повторяющееся двоичное расширение 0,1 обрезается в 52-м бите (фактически 53-й бит значителен, и он округлится в 52-й бит). Это связано с тем, что переменные с двойной точностью с плавающей точностью (тип данных MATLAB ® по умолчанию) хранятся в 64-битном формате с плавающей точностью, с 1 битом для знака, 11 битами для экспоненты и 52 битами для мантиссы плюс один «скрытый» бит для эффективного 53 битов точности. Несмотря на то, что двойная точность с плавающей точностью имеет очень большую область значений, ее точность ограничена 53 битами. Для получения дополнительной информации об арифметике с плавающей точкой см. главу 1 книги Клева Молера «Численные вычисления с MATLAB». С PDF можно ознакомиться здесь: https://www.mathworks.com/company/aboutus/founders/clevemoler.html

Итак, почему точность больше, чем точность с плавающей точкой? Поскольку большинство процессоров с фиксированной точкой имеют данные, сохраненные с меньшей точностью, а затем вычисляются с большей точностью. Для примера давайте инициализируем 40-битный беззнаковый fi и умножить используя полную точность для продуктов.

Обратите внимание, что полноточный продукт 40-битных операндов составляет 80 биты, что является большей точностью, чем стандартная двойная точность с плавающей точностью.

a = fi(0.1, 0, 40);
bin(a)
ans =

    '1100110011001100110011001100110011001101'

b = a*a
b = 

        0.0100000000000045

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 80
        FractionLength: 86
bin(b)
ans =

    '10100011110101110000101000111101011100001111010111000010100011110101110000101001'

Доступ к данным

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

DOUBLE (A

)
a = fi(pi);
double(a)
ans =

              3.1416015625

возвращает значение «реального мира» двойной точности с плавающей точкой a, квантованный к точности a.

A.DOUBLE =...

Мы также можем задать реальное значение в double.

a.double = exp(1)
a = 

             2.71826171875

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

устанавливает реальное значение a на e, квантованный к aчисловой тип.

STOREDTEGER (A

)
storedInteger(a)
ans =

  int16

   22268

возвращает «сохраненное целое число» в наименьшем доступном встроенном целом типе, до 64 бит.

Отношение между сохраненным целым значением и реальным значением

В BinaryPoint масштабирование, отношение между сохраненным целым значением и вещественным значением является

$$ \mbox{Real-world value} = (\mbox{Stored integer})\cdot
2^{-\mbox{Fraction length}}.$$

Есть также SlopeBias масштабирование, которое имеет отношение

$$ \mbox{Real-world value} = (\mbox{Stored integer})\cdot
\mbox{Slope}+ \mbox{Bias}$$

где

$$ \mbox{Slope} = (\mbox{Slope adjustment factor})\cdot
2^{\mbox{Fixed exponent}}.$$

и

$$\mbox{Fixed exponent} = -\mbox{Fraction length}.$$

Математические операторы fi работа с BinaryPoint масштабирование и реальное SlopeBias масштабированные fi объекты.

BIN (A), OCT (A), DEC (A), HEX

(A)

возвращает сохраненное целое число в двоичных, восьмеричных, беззнаковых десятичных и шестнадцатеричных строках, соответственно.

bin(a)
ans =

    '0101011011111100'

oct(a)
ans =

    '053374'

dec(a)
ans =

    '22268'

hex(a)
ans =

    '56fc'

A.BIN =..., A.OCT =..., A.DEC =..., A.HEX =...

установите сохраненное целое число из двоичных, восьмеричных, беззнаковых десятичных и шестнадцатеричных строк, соответственно.

$$\mbox{\texttt{fi}}(\pi)$$

a.bin = '0110010010001000'
a = 

              3.1416015625

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

$$\mbox{\texttt{fi}}(\phi)$$

a.oct = '031707'
a = 

           1.6180419921875

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

$$\mbox{\texttt{fi}}(e)$$

a.dec = '22268'
a = 

             2.71826171875

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

$$\mbox{\texttt{fi}}(0.1)$$

a.hex = '0333'
a = 

           0.0999755859375

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

Определение FractionLength

Когда FractionLength свойство не задано, оно вычисляется как лучшая точность для величины значения и заданного размера слова. Можно также задать длину дроби непосредственно как четвертый числовой аргумент в fi конструктор или третий числовой аргумент в sfi или ufi конструктор. В следующем сравните длину дроби a, который был явно установлен на 0, до длины дроби b, которая была установлена на лучшую точность для величины значения.

a = sfi(10,16,0)
a = 

    10

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 16
        FractionLength: 0
b = sfi(10,16)
b = 

    10

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

Обратите внимание, что сохраненные целочисленные значения a и b отличаются друг от друга, хотя их реальные значения одинаковы. Это связано с реальным значением a - сохраненное целое число, масштабируемое 2 ^ 0 = 1, в то время как значение реального мира b - сохраненное целое число, масштабированное на 2 ^ -11 = 0.00048828125.

storedInteger(a)
ans =

  int16

   10

storedInteger(b)
ans =

  int16

   20480

Определение свойств с парами параметр/значение

До сих пор мы задавали свойства числового типа, передав числовые аргументы в fi конструктор. Мы также можем задать свойства, задав имя свойства как строку, за которой следует значение свойства:

a = fi(pi,'WordLength',20)
a = 

          3.14159393310547

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

Для получения дополнительной информации о fi свойства, тип

help fi

или

doc fi

в командной строке MATLAB.

Свойства числового типа

Все числовые свойства fi инкапсулированы в объект с именем numerictype:

T = numerictype
T =


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

Свойства числового типа могут быть изменены либо при создании объекта путем передачи аргументов параметр/значение

T = numerictype('WordLength',40,'FractionLength',37)
T =


          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 40
        FractionLength: 37

или они могут быть назначены с помощью записи через точку

T.Signed = false
T =


          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 40
        FractionLength: 37

Все числовые свойства fi может быть установлен сразу путем прохождения в numerictype объект. Это удобно, например, при создании не одного fi объект с одним и тем же числовым типом.

a = fi(pi,'numerictype',T)
a = 

          3.14159265359194

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 40
        FractionLength: 37
b = fi(exp(1),'numerictype',T)
b = 

          2.71828182845638

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 40
        FractionLength: 37

The numerictype объект также может быть передан непосредственно в fi конструктор

a1 = fi(pi,T)
a1 = 

          3.14159265359194

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 40
        FractionLength: 37

Для получения дополнительной информации о numerictype свойства, тип

help numerictype

или

doc numerictype

в командной строке MATLAB.

Настройки отображения

Настройки отображения для fi может быть задан с помощью fipref объект. Они могут быть сохранены между сеансами работы с MATLAB с savefipref команда.

Отображение реальных значений

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

a = sfi(1,8,7)
a = 

                 0.9921875

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 8
        FractionLength: 7
bin(a)
ans =

    '01111111'

в то время как 100-битное дробное число не может (1 отображается, когда точное значение 1 - 2 ^ -99):

b = sfi(1,100,99)
b = 

     1

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 100
        FractionLength: 99

Обратите внимание, однако, что полная точность сохраняется во внутреннем представлении fi

bin(b)
ans =

    '0111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'

Отображение fi объект также зависит от format MATLAB команда. В частности, при отображении реальных значений удобно использовать

format long g

так, чтобы отображалась максимально возможная точность.

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

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

help fipref
help savefipref
help format

или

doc fipref
doc savefipref
doc format

в командной строке MATLAB.

Очистка

Следующий код устанавливает любые настройки или настройки отображения, которые в примере были изменены на их исходные состояния.

% Reset the fi display and logging preferences
fipref(fiprefAtStartOfThisExample);
set(0, 'format', originalFormat);
%#ok<*NOPTS,*NASGU>