VisualDSP: использование форматов переменных |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Размеры встроенных типов данных C/C++ выбраны компанией Analog Devices таким образом, чтобы обычные программы C/C++ выполнялись с подходящими под аппаратуру типами данных (hardware-native data types), что повышает быстродействие кода [2]. Рабочее окружение выполнения кода (C/C++ run-time environment) использует встроенные типы данных C/C++ и форматы данных, показанные в таблице 1-44 и на рисунках 1-4 и 1-5. Таблица 1-44. Форматы хранения данных и размеры типов данных.
Замечание: типы с плавающей запятой (floating-point) и 64-битные типы данных используются на основе программной эмуляции, поэтому они будут обрабатываться медленнее, чем традиционные, поддерживаемые аппаратно типы данных. Эмулированными являются типы float, double, long double, long long и unsigned long long. Предупреждение: традиционные типы с фиксированной запятой fract и accum недоступны в C++. На языке C они доступны только когда подключен заголовочный файл stdfix.h. Внимание: типы fract16 и fract32 не являются в действительности встроенными типами данных - они определены через typedef как short и long соответственно. На языке C для выполнения базовой арифметики нужно использовать встроенные функции (см. далее "Дробное значение встроенных функций C++", а также [4]). Вы не можете просто так выполнить умножение fract16 * fract16 и получить правильный результат. На C++ для fract-данных классы fract и shortfract определяют базовые арифметические операторы, в то время как на языке C традиционные типы с фиксированной запятой fract и accum предоставляют более натуральную альтернативу для fract16 и fract32. Таким образом, типы fract16 и fract32 имеет смысл применять только для использования с готовыми, оптимизированными (написанными на ассемблере) библиотеками [2]. [Дробное значение встроенных функций C++] Компилятор поддерживает два класса C++ для дробных чисел. Класс fract использует тип fract32 языка C для хранения дробного значения, в то время как класс shortfract использует тип fract16 языка C для хранения дробного значения. Экземпляры классов shortfract и fract инициализированные с суффиксом "r", предоставлены для работы с диапазоном чисел [-1,1). Класс fract реализован компилятором как представление внутреннего типа fract. Пример: #include < fract>
int main () { fract X = 0.5r; } Экземпляры класса shortfract могут быть инициализированы с использованием значений "r" таким же способом, однако они не представлены компилятором как внутренний тип. Вместо этого компилятор генерирует временный fract, который инициализируется с использованием значения "r". Значение класса fract затем копируется в класс shortfract с использованием неявного копирования, и временный fract уничтожается. Классы fract и shortfract содержат подпрограммы, которые позволяют выполнять базовые арифметические операции и перемещения данных в другие типы данных и из других типов данных. В примере ниже показано использование класса shortfract с операторами * и +. Математические подпрограммы для сложения, вычитания, деления и умножения для обоих классов fract и shortfract работают с использованием подпрограмм, определенных ETSI для дробных типов C (fract16 и fract32). Подключение заголовочных файлов fract и shortfract неявно определяет макрос ETSI_SOURCE как 1. Это требует использования подпрограмм ETSI, которые определены в libetsi.h, и находятся в библиотеках libetsi53*.dlb. #include < shortfract>
#include < stdio.h>
#define N 20 shortfract x[N] = { .5r,.5r,.5r,.5r,.5r, .5r,.5r,.5r,.5r,.5r, .5r,.5r,.5r,.5r,.5r, .5r,.5r,.5r,.5r,.5r}; shortfract y[N] = { 0,.1r,.2r,.3r,.4r, .5r,.6r,.7r,.8r,.9r, .10r,.1r,.2r,.3r,.4r, .5r,.6r,.7r,.8r,.9r}; shortfract fdot(int n, shortfract *x, shortfract *y) { int j; shortfract s; s = 0; for (j=0; j < n; j++) { s += x[j] * y[j]; } return s; } int main(void) { fdot(N,x,y); } [Формат IEEE для чисел с плавающей запятой] По умолчанию компилятор Blackfin предоставляет эмуляцию плавающей точки с использованием форматов IEEE одиночной и двойной точности. Одиночная точность (Single-precision IEEE format, см. рис. 1-4) представлена 32-разрядным значением, где 23 бита используются для мантиссы, 8 бит для экспоненты, и 1 бит для знака. Этот формат используется для типа данных float, а также по умолчанию для типа данных double, и когда используется ключ командной строки компилятора -double-size-32. Рис. 1-4. Обычный формат хранения чисел float и double (одинарная точность). На рис. 1-4 одно слово (32-бита) данных применено для выражения: Здесь: • Sign - представляет бит знака (sign). Формат двойной точности (Double-precision IEEE format, см. рис. 1-5) представлен 64-разрядным значением, с 52 битами для мантиссы, 11 битами для экспоненты и 1 битом для знака. Этот формат используется для типа данных long double, и для типа данных double, когда используется ключ командной строки компилятора -double-size-64. Рис. 1-5. Формат двойной точности IEEE. На рис. 1-5 двойное слово (64-бита) данных применено для выражения: Здесь: • Sign - представляет бит знака (sign). [Ссылки] 1. VisualDSP: использование типов с фиксированной точкой. |