В этом примере показаны основы использования числового объекта с фиксированной точкой fi
.
Числовой объект с фиксированной точкой называется fi
потому что Джей Х. Уилкинсон использовал 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
конструктор. Получившееся значение с фиксированной точкой называется 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
(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'
Доступ к данным может быть выполнен несколькими способами, которые сопоставляются со встроенными типами данных и двоичными строками. Для примера,
a = fi(pi); double(a)
ans = 3.1416015625
возвращает значение «реального мира» двойной точности с плавающей точкой 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
масштабирование, отношение между сохраненным целым значением и вещественным значением является
Есть также SlopeBias
масштабирование, которое имеет отношение
где
и
Математические операторы fi
работа с BinaryPoint
масштабирование и реальное SlopeBias
масштабированные fi
объекты.
возвращает сохраненное целое число в двоичных, восьмеричных, беззнаковых десятичных и шестнадцатеричных строках, соответственно.
bin(a)
ans = '0101011011111100'
oct(a)
ans = '053374'
dec(a)
ans = '22268'
hex(a)
ans = '56fc'
установите сохраненное целое число из двоичных, восьмеричных, беззнаковых десятичных и шестнадцатеричных строк, соответственно.
a.bin = '0110010010001000'
a = 3.1416015625 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
a.oct = '031707'
a = 1.6180419921875 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
a.dec = '22268'
a = 2.71826171875 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
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
Свойства числового типа могут быть изменены либо при создании объекта путем передачи аргументов параметр/значение
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>