exponenta event banner

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

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

Примечание

Вызывается числовой объект с фиксированной точкой fi потому что J.H. Wilkinson использовал fi для обозначения вычислений с фиксированной точкой в его классических текстах «Ошибки округления в алгебраических процессах» (1963) и «Проблема алгебраических собственных значений» (1965).

Установка

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

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 конструктор. Результирующее значение с фиксированной точкой называется 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

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

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 =...

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

a.double = exp(1)
a = 

             2.71826171875

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

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

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

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

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

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>