Учебный курс. Микро Паскаль. Типы данных. Часть вторая.

AVR
Статья №3.
В прошлой статье мы ознакомились с предопределенными типами данных. Продолжаем.
В Паскале, вместе с предопределенными типы данных существуют и типы данных, определенные пользователем. Описание нового типа начинается с зарезервированного слова type. Несколько примеров объявлений новых типов.

type
 array10 = array [0..10] of byte;
 string5 = string[5];


В первом примере мы создали тип – массив, размером 10 байт, во втором строку размером пять символов. Эти идентификаторы типов можно использовать в разделе переменных:

var
 a: array10;
 s: string5;


Особого практического смысла вышеуказанный пример не имеет. Можно просто в разделе переменных создать нужную переменную сразу, без всяких типов. Гораздо интереснее обстоит дело с типом запись, о котором упоминал в прошлой статье.

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

Пример создания типа запись:

type
 my_type = record
  b: byte;
  x,y: integer;
  s: string[4];
 end;


Его объявление в разделе переменных:


var
dat: my_type;


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

dat.s := 'ABCD';
dat.b:= 255;
dat.x := -100;
dat.y := 34;


еще один способ доступа к полям – оператор with. дает понять компилятору, что далее идет работа с полями типа запись. В этом случае имя переменной указывается после оператора with, а доступ к полям переменной идет по имени поля:

with dat do
 begin
    s := 'ABCD';
    b:= 255;
    x := -100;
    y := 34;
 end;


В стандартном паскале, есть еще записи с вариантами, но в Микро Паскале они не реализованы. Их мы рассматривать не будем.
Так же в Паскале существуют еще типы множества, скалярные типы, булев тип, не реализованные в Микро Паскале.

Совместимость типов.

Совместимость необходима, когда значение какого-то выражения присваивается переменной или функции. Это возможно в следующих случаях:
Т1 и Т2 – идентичные типы.
Т1 и Т2 – совместимые порядковые типы и значение типа Т2 находится в границах возможных значений объекта типа Т1;
Т1 – вещественный тип, а Т2 – целый;
Т1 и Т2 – строки;
Т1 – строка, а Т2 – символ;

Иногда нужно использовать в операторах присвоения или подпрограммах переменные разных типов. В Паскале есть механизм приведения типов. Например объявлены две переменные:

var
 c:char;
b:byte;

Тогда допустимы следующие операторы присвоения:
c := char (192);// в переменной c после присвоения будет символ А
b := byte (‘А’);// в переменной и после присвоения будет число 192.

Следует быть осторожным с приведением типов. Например

var
i:integer;
w:word;
begin
w:= 65500;
i:= integer(w);


В переменной I вместо ожидаемого 65500 мы получим –36.

Если речь зашла о переменных, расскажу о представлении различных систем счисления в Паскале. В Микро Паскале существуют три вида систем. Десятичная, Шестнадцатеричная и двоичная.
С десятеричной все ясно. Как записал так оно и будет. Для указания другой системы счисления, перед числом нужно указать специальный символ. Для шестнадцатеричной системы это символ $ или пара символов 0x. Для двоичной это %.Пример записи в различных системах счисления:

$A0
0xFF


В шестнадцатеричном виде и

%10101010 

в двоичном виде.

О переводе из одной системы счисления в другую писать не буду. Без меня много написано.
  • +1
  • 14 марта 2011, 21:20
  • Rom

Комментарии (12)

RSS свернуть / развернуть
Скажем так, тип Boolean условно реализован. Выделенного типа нет, но есть константы True (число, где все биты единички) и False (ноль), а в логических операциях, как я понял, работают подобно С, т.е. любое ненулевое значение — True.
0
  • avatar
  • Vga
  • 14 марта 2011, 21:59
Приветствую.
Не хватает мне емкости 4-байтового Real. В Delphi те же вычисления дают приемлемую точность только с использованием Extended (10 байт).
Можно ли каким как-то повысить точность вычислений в микропаскале?
0
Вы там число Пи считаете микроконтроллером что ли?
0
По двум точкам в WGS-84 считаю азимут
0
Не хватает мне емкости 4-байтового Real. Можно ли каким как-то повысить точность вычислений в микропаскале?
Используйте longint (-2147483648… 2147483647) или dword (0… 4294967295), где все цифры — точные. Если ваши числа больше, или дробные — предварительно отмасштабируйте, сдвинув запятую вправо или влево (соответствует умножению или делению на несколько десяток), соответственно скорректировав потом результат вычислений.

Я всегда стараюсь использовать целочисленные типы и вычисления (даже в программах на Дельфи). Кроме более высокой точности, чем с плавающей точкой, на микроконтроллерах дает заметное повышение скорости вычислений и уменьшает размер кода.
0
  • avatar
  • SWG
  • 19 сентября 2012, 10:11
Думал уже об этом, но у меня пересчет географических координат в азимут. Там тригонометрия…
0
Ну, можно написать свою реализацию тригонометрических функций для чисел с фиксированной точкой. Например, через разложение в ряд Тейлора (хотя, подозреваю, что есть более оптимизированные алгоритмы).
0
Проблема в нелинейности. При малых значениях важны доли, при больших на них класть можно. можно конечно формулы приближения задействовать и считать разными ветками при разных величинах. Но как то монструозно выйдет.
0
Если нужно вычислять с разной точностью, можно прямо в функцию передавать аргумент, до какого члена вычислять разложение в ряд. Правда, тогда циклы поразворачивать не получится.
0
Ну у тебя и требования.
Непосредственно — никак. Могу посоветовать несколько вариантов:
1) Использовать другой компилятор. Скажем, тот же GCC поддерживает Double.
2) Написать свою математику с плавающей запятой с требуемой точностью чисел. Все равно на практически всех МК FP софтовый. Кстати, если у тебя такой расчет, что успевают накопиться ошибки даже с Double — на МК он вероятно будет идти охрененно долго.
3) Оптимизировать расчеты. Часто приближенный упрощенный алгоритм дает более точные результаты чем точный, из-за накопления погрешностей. Кроме того, возможно ты неправильно работаешь с флоатом, не учитывая ограниченность его точности.
0
  • avatar
  • Vga
  • 19 сентября 2012, 10:18
Спасибо. Расчеты временем не сильно ограничены. Буду думать над своей математикой. Может подскажете в какую сторону копать?
0
Могу предложить принцип bignum. Выделяете сколько вам надо байт данных. Сложение, вычитание, деление, умножение «в столбик» (пример можно глянуть у Генри Уоррен мл. — Алгоритмические трюки для програмистов). Но вот с тригонометрией хз.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.