Самостоятельная работа «перевод единиц длины (пути) в си»

Введение

Мир вокруг можно моделировать различными способами. Самым естественным из них является представление о нём, как о наборе объектов. У каждого объекта есть свои свойства.
Например, для человека это возраст, пол, рост, вес и т.д. Для велосипеда – тип, размер колёс, вес, материал, изготовитель и пр. Для товара в магазине – идентификационный номер,
название, группа, вес, цена, скидка и т.д.

У классов объектов набор этих свойств одинаковый: все собаки могут быть описаны, с той или иной точностью, одинаковым набором свойств, но значения этих свойств будут разные.

Все самолёты обладают набором общих свойств в пределах одного класса. Если же нам надо более точное описание, то можно выделить подклассы: самолёт амфибии, боевые
истребители, пассажирские лайнеры – и в пределах уже этих классов описывать объекты.
Например, нам необходимо хранить информацию о сотрудниках компании. Каждый сотрудник, в общем, обладает большим количеством разных свойств.
Мы выберем только те, которые нас интересуют для решения прикладной задачи: пол, имя, фамилия, возраст, идентификационный номер. Для работы с таким
объектом нам необходима конструкция, которая бы могла агрегировать различные типы данных под одним именем. Для этих целей в си используются структуры.

Логические операции

Логические операции делятся на две группы:

  • условные;
  • побитовые.

Условные логические операции чаще всего используются в операциях проверки условия if и могут выполняться над любыми объектами. Результат условной логической операции:

  • 1 если выражение истинно;
  • если выражение ложно.

Вообще, все значения, отличные от нуля, интерпретируются условными логическими операциями как истинные.
Основные условные логические операции:

  • && — И (бинарная) — требуется одновременное выполнение всех операций отношения;
  • || — ИЛИ (бинарная) — требуется выполнение хотя бы одной операции отношения;
  • ! — НЕ (унарная) — требуется невыполнение операции отношения.

 Побитовые логические операции оперируют с битами, каждый из которых может принимать только два значения: 0 или 1.
Основные побитовые логические операции в языке Си:

  • & конъюнкция (логическое И) — бинарная операция, результат которой равен 1 только когда оба операнда единичны (в общем случае — когда все операнды единичны);
  • | дизъюнкция (логическое ИЛИ) — бинарная операция, результат которой равен 1 когда хотя бы один из операндов равен 1;
  • ~ инверсия (логическое НЕ) — унарная операция, результат которой равен 0 если операнд единичный, и равен 1, если операнд нулевой;
  • ^ исключающее ИЛИ — бинарная операция, результат которой равен 1, если только один из двух операндов равен 1 (в общем случае если во входном наборе операндов нечетное число единиц).

 
Для каждого бита результат выполнения операции будет получен в соответствии с таблицей.

a b a & b a | b ~a a ^ b
1
1 1 1 1
1 1 1
1 1 1 1

Пример:

1234567

unsigned char a = 14;    // a = 0000 1110unsigned char b = 9;     // b = 0000 1001unsigned char c, d, e, f;c = a & b;               // c = 8 = 0000 1000d = a | b;               // d = 15 = 0000 1111e = ~a;                  // e = 241 = 1111 0001f = a ^ b;               // f = 7 = 0000 0111

маскирование битов

Бит Маска
0x01
1 0x02
2 0x04
3 0x08
4 0x10
5 0x20
6 0x40
7 0x80

Для установки определенного бита необходимо соответствующий бит маски установить в 1 и произвести операцию побитового логического ИЛИ с константой, представляющей собой маску:

12

unsigned char a = 3;a = a | 0x04;  // a = 7, бит 2 установлен

12

unsigned char a = 3;a = a & (~0x02);  // a = 1, бит 1 сброшен

  • объект &= выражение; // объект = объект & выражение
  • объект |= выражение; // объект = объект | выражение
  • объект ^= выражение; // объект = объект ^ выражение

История

Международный эталон метра, использовавшийся с 1889 по 1960 год

СИ является развитием метрической системы мер, которая была создана французскими учёными и впервые широко внедрена после Великой французской революции. До введения метрической системы единицы выбирались независимо друг от друга, поэтому пересчёт из одной единицы в другую был сложным. К тому же в разных местах применялись разные единицы, иногда с одинаковыми названиями. Метрическая система должна была стать удобной и единой системой мер и весов.

В начале 1790-х годов во Франции были изготовлены временные эталоны метра и килограмма. Копии эталонов были отправлены, в частности, в США, но корабль с копиями был захвачен британскими каперами, так что они не дошли до Америки; возможно, это сыграло роль в том обстоятельстве, что СИ плохо приживается в США тогда и до сих пор.

В 1799 году во Франции были изготовлены два эталона — для единицы длины (метр) и для единицы массы (килограмм).

В 1832 году немецкий математик Карл Гаусс разработал научные основы построения систем единиц и создал новую систему. В качестве основных физических величин он принял длину, массу и время, а в качестве основных единиц — миллиметр, миллиграмм и секунду. Впоследствии эта система послужила базой для разработки системы СГС.

В 1874 году британскими физиками Джеймсом Максвеллом и Уильямом Томпсоном была представлена система СГС, основанная на трёх единицах — сантиметр, грамм и секунда — и десятичных приставках от микро до мега.

В 1875 году представителями семнадцати государств (Россия, Германия, США, Франция, Италия и др.) была подписана Метрическая конвенция, в соответствии с которой были созданы Международный комитет мер и весов (фр. Comité International des Poids et Mesures, CIPM) и Международное бюро мер и весов (фр. Bureau International des Poids et Mesures, BIPM), а также предусмотрен регулярный созыв Генеральных конференций по мерам и весам (ГКМВ) (фр.  Conférence Générale des Poids et Mesures, CGPM). Были начаты работы по разработке международных эталонов метра и килограмма.

В 1889 году ГКМВ приняла систему единиц МКС, сходную с СГС, но основанную на метре, килограмме и секунде, так как эти единицы были признаны более удобными для практического использования.

В последующем были введены основные единицы для физических величин в области электричества и оптики.

В 1948 году Международный союз теоретической и прикладной физики и французское правительство обратились к IX ГКМВ со своими предложениями о международной унификации единиц

Приняв во внимание эти обращения, ГКМВ поручила Международному комитету мер и весов выработать рекомендации по созданию единой практической системы единиц измерения, пригодной для принятия всеми государствами участниками Метрической конвенции. В развитие данного решения X ГКМВ в 1954 году приняла в качестве основных единиц вновь разрабатываемой системы следующие шесть единиц: метр, килограмм, секунда, ампер, градус Кельвина, кандела.

В 1956 году Международный комитет мер и весов рекомендовал, чтобы системе единиц, базирующейся на основных единицах, принятых X ГКМВ, было присвоено наименование «Système International d’Unités».

В 1960 году XI ГКМВ приняла стандарт, который впервые получил название «Международная система единиц», и установила международное сокращённое наименование этой системы «SI». Основными единицами в ней стали метр, килограмм, секунда, ампер, градус Кельвина и кандела.

С 1 января 1963 года ГОСТом 9867-61 «Международная система единиц» СИ была введена в СССР в качестве предпочтительной во всех областях науки, техники и народного хозяйства, а также при преподавании.

XIII ГКМВ (1967—1968) приняла новое определение единицы термодинамической температуры, присвоила ей имя «кельвин» и обозначение «К» (ранее единица называлась «градус Кельвина», а её обозначением был «°K»).

XIII ГКМВ (1967—1968) приняла новое определение секунды.

В 1971 году XIV ГКМВ внесла изменения в СИ, добавив, в частности, в число основных единиц единицу количества вещества (моль).

В 1979 году XVI ГКМВ приняла новое определение канделы.

В 1983 году XVII ГКМВ дала новое определение метра.

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

Таблица единиц измерения величин РФ. Таблица единиц измерения величин ЕС. Система СИ. International System of Units (French: Système international d’unités, SI). Units of measurement EU, RF.

Основные единицы СИ —  официальная система единиц измерения для РФ и ЕС

Величина Единица
Наименование Символ размерности Наименование Обозначение
русское французское/английское русское международное
Длина L метр mètre/metre м m
Масса M килограмм kilogramme/kilogram кг kg
Время T секунда seconde/second с s
Сила электрического тока I ампер ampère/ampere А A
Термодинамическая температура Θ кельвин kelvin К K
Количество вещества N моль mole моль mol
Сила света J кандела candela кд cd

Производные единицы СИ

  • Производные единицы могут быть выражены через основные с помощью математических операций — умножения и деления. Некоторым из производных единиц для удобства присвоены собственные наименования, такие единицы тоже можно использовать в математических выражениях для образования других производных единиц.
  • Математическое выражение для производной единицы измерения вытекает из физического закона, с помощью которого эта единица измерения определяется, или из определения физической величины, для которой она вводится. Например, скорость — это расстояние, которое тело проходит в единицу времени; соответственно, единица измерения скорости — м/с (метр в секунду).
  • Часто одна и та же единица может быть записана по-разному, с помощью разного набора основных и производных единиц (см. последний столбец таблицы). Однако на практике используются установленные (или просто общепринятые) выражения, которые наилучшим образом отражают физический смысл величины. Например, для записи значения момента силы следует использовать Н·м, и не следует использовать м·Н или Дж.
  • Наименование некоторых производных единиц, имеющих одинаковое выражение через основные единицы, может быть разным. Например, единица измерения «секунда в минус первой степени» (1/с) называется герц (Гц), когда она используется для измерения частоты, и называется беккерель (Бк), когда она используется для измерения активности радионуклидов.
Производные единицы, имеющие специальные наименования и обозначения
Величина Единица Обозначение Выражение через основные единицы
русское наименование французское/английское
наименование
русское международное
Плоский угол радиан radian рад rad м·м−1 = 1
Телесный угол стерадиан steradian ср sr м2·м−2 = 1
Температура Цельсия градус Цельсия degré Celsius/degree Celsius °C °C K
Частота герц hertz Гц Hz с−1
Сила ньютон newton Н N кг·м·c−2
Энергия джоуль joule Дж J Н·м = кг·м2·c−2
Мощность ватт watt Вт W Дж/с = кг·м2·c−3
Давление паскаль pascal Па Pa Н/м2 = кг·м−1·с−2
Световой поток люмен lumen лм lm кд·ср
Освещённость люкс lux лк lx лм/м² = кд·ср/м²
Электрический заряд кулон coulomb Кл C А·с
Разность потенциалов вольт volt В V Дж/Кл = кг·м2·с−3·А−1
Сопротивление ом ohm Ом Ω В/А = кг·м2·с−3·А−2
Электроёмкость фарад farad Ф F Кл/В = с4·А2·кг−1·м−2
Магнитный поток вебер weber Вб Wb кг·м2·с−2·А−1
Магнитная индукция тесла tesla Тл T Вб/м2 = кг·с−2·А−1
Индуктивность генри henry Гн H кг·м2·с−2·А−2
Электрическая проводимость сименс siemens См S Ом−1 = с3·А2·кг−1·м−2
Активность радиоактивного источника беккерель becquerel Бк Bq с−1
Поглощённая доза ионизирующего излучения грей gray Гр Gy Дж/кг = м²/c²
Эффективная доза ионизирующего излучения зиверт sievert Зв Sv Дж/кг = м²/c²
Активность катализатора катал katal кат kat моль/с

Другие типы данных

 
Программа, написанная на языке Си, оперирует с данными различных типов. Все данные имеют имя и тип. Обращение к данным в программе осуществляется по их именам (идентификаторам).Идентификатор — это последовательность, содержащая не более 32 символов, среди которых могут быть любые буквы латинского алфавита a — z, A — Z, цифры 0 — 9 и знак подчеркивания (_). Первый символ идентификатора не должен быть цифрой.
Несмотря на то, что допускается имя, имеющее до 32 символов, определяющее значение имеют только первые 8 символов. Помимо имени, все данные имеют тип. Указание типа необходимо для того, чтобы было известно, сколько места в оперативной памяти будет занимать данный объект.
Компилятор языка Си придерживается строгого соответствия прописных и строчных букв в именах идентификаторов и лексем.

Верно Неверно
int a = 2, b;
b = a+3;
Int a=2;  // правильно int
INT a=2;
int a = 2, b;
b = A + 3; // идентификатор А не объявлен
int a = 2;
b = a + 3; // идентификатор b не объявлен

Строковые константы

Строковая константа — это последовательность символов, заключенная в кавычки, например:

«Это строковая константа»

Кавычки не входят в строку, а лишь ограничивают её. Технически строковая константа представляет собой массив символов, и по этому признаку может быть отнесена к разряду сложных объектов языка Си.
В конце каждой строковой константы компилятор помещает ‘\0’ (нуль-символ), чтобы программе было возможно определить конец строки. Такое представление означает, что размер строковой константы не ограничен каким-либо пределом, но для определения длины строковой константы её нужно полностью просмотреть.
Поскольку строковая константа состоит из символов, то она имеет тип char. Количество ячеек памяти, необходимое для хранения строковой константы на 1 больше количества символов в ней (1 байт используется для хранения нуль-символа).
Символьная константа ‘x’ и строка из одного символа «x» — не одно и то же. Символьная константа — это символ, используемый для числового представления буквы x, а строковая константа «x» содержит символ ‘x’ и нуль-символ ‘\0’ и занимает в памяти 2 байта. Если в программе строковые константы записаны одна за другой через разделители, то при выполнении программы они будут размещаться в последовательных ячейках памяти. 

Устройство структуры в памяти

Поля структуры расположены в памяти друг за другом. Тип поля определяет сдвиг относительно предыдущего поля. Имя поля — это сдвиг относительно адреса экземпляра.
На самом деле размер структуры не всегда равен сумме размеров её полей: это связано с тем, что компилятор оптимизирует расположение структуры в памяти и может поля
небольшого размера подгонять до чётных адресов.

Представление структуры в памяти.

#include 
#include 

struct Test1 {
	char a;
	char b;
	int c;
} A;

struct Test2 {
	int x;
	int y;
} B;

struct Test3 {
	char a;
	char b;
	char c;
	int d;
} C;

void main() {
	printf("sizeof(A) = %d\n", sizeof(A));
	printf("sizeof(B) = %d\n", sizeof(B));
	printf("sizeof(C) = %d\n", sizeof(C));

	getch();
}

Первая структура должна иметь размер 6 байт, вторая 8 байт, третья 7 байт, однако на 32-разрядной машине компилятор VC сделает их все три равными 8 байт.
Стандарт гарантирует, что поля расположены друг за другом, но не гарантирует, что непрерывно.

Есть возможность изменить упаковку структур в памяти. Можно явно указать компилятору каким образом производить упаковку полей структуры, объединений или полей класса. Каким
образом это делать, зависит от компилятора. Один из самых распространённых способов прагма pack()

#pragma pack(n)

Использование #pragma pack не приветствуется: логика работы программы не должна зависить от внутреннего представления структуры (если, конечно, вы не занимаетесь
системным программированием или ломаете чужие программы и сети).

Приведение типов

Стандартом поведение при приведении одной структуры к другой не определено. Это значит, что даже если структуры имеют одинаковые поля, то нельзя явно
кастовать одну структуру до другой.

#include 
#include 

struct Point {
	int x;
	int y;
};

struct Apex {
	int a;
	int b;
};

void main() {
	struct Point point = {10, 20};
	struct Apex apex;

	apex = (*(struct Apex*)(&point));

	printf("a = %d, b = %d", apex.a, apex.b);

	getch();
}

Этот пример работает, но это хак, которого необходимо избегать. Правильно писать так

void main() {
	struct Point point = {10, 20};
	struct Apex apex;

	apex.a = point.x;
	apex.b = point.y;

	printf("a = %d, b = %d", apex.a, apex.b);

	getch();
}

Привести массив к структуре (или любому другому типу) по стандарту также невозможно (хотя в различных компиляторах есть для этого инструменты).
Но в си возможно всё.

#include 
#include 

struct Point {
	int x;
	int y;
};

void main() {
	struct Point point = {10, 20};
	int x = {300, 400, 500};

	point = (*(struct Point*)(x));

	printf("a = %d, b = %d", point.x, point.y);

	getch();
}

Но запомните, что в данном случае поведение не определено.

Правила написания обозначений единиц

См. также:

  • Обозначения единиц печатают прямым шрифтом, точку как знак сокращения после обозначения не ставят.
  • Обозначения помещают за числовыми значениями величин через пробел, перенос на другую строку не допускается. Примеры: 10 м/с, 15 °С. Исключения составляют обозначения в виде знака над строкой, перед ними пробел не ставится, например 15°.
  • Если числовое значение представляет собой дробь с косой чертой, его заключают в скобки, например (1/60) с−1.
  • При указании значений величин с предельными отклонениями их заключают в скобки или проставляют обозначение единицы за числовым значением величины и за её предельным отклонением: (100,0 ± 0,1) кг, 50 г ± 1 г.
  • Обозначения единиц, входящие в произведение, отделяют точками на средней линии (Н·м, Па·с), не допускается использовать для этой цели символ «×». В машинописных текстах допускается точку не поднимать или разделять обозначения пробелами, если это не может вызвать недоразумения.
  • В качестве знака деления в обозначениях можно использовать горизонтальную черту или косую черту (только одну). При применении косой черты, если в знаменателе стоит произведение единиц, его заключают в скобки. Правильно: Вт/(м·К), неправильно: Вт/м/К, Вт/м·К.
  • Допускается применять обозначения единиц в виде произведения обозначений единиц, возведённых в степени (положительные и отрицательные): Вт·м−2·К−1, А·м2. При использовании отрицательных степеней не разрешается использовать горизонтальную или косую черту (знак деления).
  • Допускается применять сочетания специальных знаков с буквенными обозначениями, например °/с (градус в секунду).
  • Не допускается комбинировать обозначения и полные наименования единиц. Неправильно: км/час, правильно: км/ч.
  • Обозначения единиц, произошедшие от фамилий, пишутся с заглавной буквы, в том числе с приставками СИ, например: ампер — А, мегапаскаль — МПа, килоньютон — кН, гигагерц — ГГц.

Объявление структуры

Синтаксис объявления структуры

struct  {
	 ;
	 ;
	...
	 ;
};

Например

struct point_t {
	int x;
	int y;
}; //Тут стоит точка с запятой!

Полями структуры могут быть любые объявленные типы, кроме самой структуры этого же типа, но можно хранить указатель на структуру этого типа:

struct node {
	void* value;
	struct node next;
};

Нельзя, нужно

struct node {
	void* value;
	struct node *next;
};

В том случае, если несколько полей имеют один тип, то их можно перечислить через запятую:

struct Point3D {
	int x, y, z;
};

После того, как мы объявили структуру, можно создавать переменную такого типа с использованием служебного слова struct. Доступ до полей структуры осуществляется с
помощью операции точка:

#include 
#include 
#include 

struct point_t {
	int x;
	int y;
};

void main() {
	struct point_t A;
	float distance;

	A.x = 10;
	A.y = 20;

	distance = sqrt((float) (A.x*A.x + A.y*A.y));

	printf("x = %.3f", distance);
	getch();
}

Структура, объявленная в глобальном контексте, видна всем. Структура также может быть объявлена внутри функции:

#include 
#include 
#include 

void main() {
	struct point_t {
		int x;
		int y;
	};
	struct point_t A;
	float distance;

	A.x = 10;
	A.y = 20;

	distance = sqrt((float) (A.x*A.x + A.y*A.y));

	printf("x = %.3f", distance);
	getch();
}

Можно упростить пример: синтаксис языка позволяет создавать экземпляры структуры сразу же после определения:

struct point_t {
		int x;
		int y;
	} A;
	float distance;

Структура также может быть анонимной. Тогда мы не сможем использовать имя структуры в дальнейшем.

#include 
#include 
#include 

void main() {
	struct {
		int x;
		int y;
	} A;
	float distance;

	A.x = 10;
	A.y = 20;

	distance = sqrt((float) (A.x*A.x + A.y*A.y));

	printf("x = %.3f", distance);
	getch();
}

В этом примере мы создали переменную A. Она является структурой с двумя полями.

Непечатные символы

В си определён ряд символов, которые не выводятся на печать, но позволяют производить форматирование вывода. Эти символы
можно задавать в виде численных значений, либо в виде эскейп-последовательностей: символа, экранированного обратным слешем.

#include 
#include 

void main() {
	char backspace = 0x08;
	//Выводим с использованием символа переноса строки
	printf("Hello\nWorld\n");
	//Выводим символ переноса строки через его значение
	printf("Hello%cWorld\n", 0x0a);
	//"Выводим" сигнал
	printf("\a");
	//Выводим сигнал, как символ
	printf("%c", '\a');
	//Выводим сигнал через шестнадцатеричное значение
	printf("%c", 0x07);
	printf("This is sparta!!!\b\b%c", backspace);
	printf("   ");
	getch();
}

Q&A

Всё ещё не понятно? – пиши вопросы на ящик

Определение нового типа

Когда мы определяем новую структуру с помощью служебного слова struct, в пространстве имён структур (оно не имеет ничего общего с пространствами имён С++) создаётся новый идентификатор. Для доступа к нему необходимо использовать служебное слово struct.
Можно определить новый тип с помощью служебного слова typedef. Тогда будет создан псевдоним для нашей структуры, видимый в глобальном контексте.

#include 
#include 

//Определяем новую структуру
struct point_t {
	int x;
	int y;
};

//Определяем новый тип
typedef struct point_t Point;

void main() {
	//Обращение через имя структуры
	struct point_t p = {10, 20};
	//Обращение через новый тип
	Point px = {10, 20};

	getch();
}

Теперь при работе с типом Point нет необходимости каждый раз писать слово struct. Два объявления можно объединить в одно

typedef struct point_t {
	int x;
	int y;
} Point;

Замечание. Если мы создаём новый тип-структуру, полем которого является указатель на этот же тип, то его необходимо объявлять явно с использованием служебного слова struct

typedef struct Node {
	int value;
	struct Node *next;
} Node;

Указатели на поля структуры и на вложенные структуры

Указатели на поля структуры определяются также, как и обычные указатели. Указатели на вложенные структуры возможны только тогда,
когда структура определена. Немного переделаем предыдущий пример: «деанонимизируем» вложенную безымянную структуру и
возьмём указатели на поля структуры Model:

#include 
#include 
#include 
#include 

#define YEAR_OFFSET 1890

//Отдельно выделили структуру "Марка"
typedef struct Make {
	int id;
    char *name;
} Make;

//Теперь полем структуры "Модель" является структура "Марка"
typedef struct Model {
    int id;
	Make make;
    char *name;
    unsigned char year; //year is an offset to 1890
} Model;

char* mallocByString(const char *str) {
    char* p = (char*) malloc(strlen(str) + 1);
    strcpy(p, str);
    return p;
}
 
void freeModel(Model* model) {
    free(model->make.name);
    free(model->name);
}

void main() {
	Make *make = NULL;
	Model cl;
	int *id;

    cl.id = 2;
    cl.make.id = 1;
    cl.make.name = mallocByString("Acura");
    cl.name = mallocByString("CL");
    cl.year = (2003 - YEAR_OFFSET);

	//Получаем указатель на вложенную структуру
	make = &cl.make;
	//Получаем указатель на поле структуры
	id = &cl.id;
	printf("make.name = %s\n", make->name);
	printf("make.id = %d\n", make->id);
	printf("model.id = %d\n", *id);

	freeModel(&cl);
	scanf("1");
}

Как уже говорилось ранее, в си, даже если у двух структур совпадают поля, но структуры имеют разные имена, то их нельзя приводить к одному типу. Поэтому
приходится избавляться от анонимных вложенных структур, если на них нужно взять указатель. Можно попытаться взять указатель типа char*
на поле структуры, но нет гарантии, что поля будут расположены непрерывно.

Начальная инициализация структур

Структуру можно инициализировать во время создания как массив. Поля в этом случае будут присваиваться по порядку.

#include 
#include 
#include 

struct gasket {
	float weight;
	unsigned height;
	unsigned diameter;
};

void main() {
	struct gasket obj = { 12.f, 120, 30 };

	printf("gasket info:\n");
	printf("-------------------\n");
	printf("weight: %4.3f kg\n", obj.weight);
	printf("height: %6d cm\n", obj.height);
	printf("diameter: %4d cm\n", obj.diameter);

	getch();
}

Замечание: таким образом можно только иницализировать структуру. Присваивать значение всей структуре таким образом нельзя.

Современный стандарт си позволяет инициализировать поля структуры по имени. Для этого используется следующий синтакис:

#include

typedef struct thing {
    int a;
    float b;
    const char *c;
} thing_t;

int main() {
    thing_t t = {
        .a = 10,
        .b = 1.0,
        .c = "ololololo"
    };
    printf("%s\n", t.c);
    printf("%d\n", t.a);
    printf("%f\n", t.b);
    _getch();
}

Вещественные данные

Вещественный тип предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме.Нормированная форма числа предполагает наличие одной значащей цифры (не 0) до разделения целой и дробной части. Такое представление умножается на основание системы счисления в соответствующей степени. Например, число 12345,678 в нормированной форме можно представить как

12345,678 = 1,2345678·104

Число 0,009876 в нормированной форме можно представить как

0,009876 = 9,876·10-3

В двоичной системе счисления значащий разряд, стоящий перед разделителем целой и дробной части, может быть равен  только 1. В случае если число нельзя представить в нормированной форме (например, число 0), значащий разряд перед разделителем целой и дробной части равен 0.
Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа.
В общем случае вещественное число в разрядной сетке вычислительной машины можно представить в виде 4 полей.

  • знак — бит, определяющий знак вещественного числа (0 для положительных чисел, 1 — для отрицательных).
  • степень — определяет степень 2, на которую требуется умножить число в нормированной форме. Поскольку степень 2 для числа в нормированной форме может быть как положительной, так и отрицательной, нулевой степени 2 в представлении вещественного числа соответствует величина сдвига, которая определяется как

    2n-1,

    где n — количество разрядов, отводимых для представления степени числа.

  • целое — бит, который для нормированных чисел всегда равен 1, поэтому в некоторых представлениях типов этот бит опущен и принимается равным 1.
  • мантисса — значащие разряды представления числа, стоящие после разделителя целой и дробной части в нормированной форме.

 
Различают три основных типа представления вещественных чисел в языке Си:

Тип Обозна-
чение в Си
Кол-во бит Биты степени Мантисса Сдвиг
простое float 32 30…23 22…0 127
двойной точности double 64 62…52 51…0 1023
двойной расширен- ной точности long double 80 78…64 62…0 16383

Как видно из таблицы, бит целое у типов float и double отсутствует. При этом диапазон представления вещественного числа состоит из двух диапазонов, расположенных симметрично относительно нуля. Например, диапазон представления чисел типа float можно представить в виде:Пример: представить число -178,125 в 32-разрядной сетке (тип float).
Для представления числа в двоичной системе счисления преобразуем отдельно целую и дробную части:

17810 = 101100102.

0,12510 = 0,0012.

Тогда

178,12510 = 10110010,0012=1,0110010001·2111

Для преобразования в нормированную форму осуществляется сдвиг на 7 разрядов влево).
Для определения степени числа применяем сдвиг:

0111111+00000111 = 10000110.

Таким образом, число -178,125 представится в разрядной сетке как

 

Критика СИ

Несмотря на широкое распространение СИ, во многих научных работах по электродинамике используется Гауссова система единиц, что вызывается рядом недостатков СИ, на которые указывают М. А. Леонтович, С. П. Капица, Д. В. Сивухин, Л. Б. Окунь и ряд других физиков. Система единиц СГС и система единиц СИ эквивалентны во многих разделах физики, но если обратиться к электродинамике, то в СИ возникают не имеющие непосредственного физического смысла величины, унаследованные от концепции эфира как материальной среды, — электрическая постоянная и магнитная постоянная (в старой терминологии — электрическая и магнитная проницаемости вакуума). Вследствие этого в системе единиц СИ электрическое поле и электрическая индукция, магнитное поле и магнитная индукция (в сущности — различные компоненты тензора электромагнитного поля) имеют разную размерность. Такую ситуацию Д. В. Сивухин характеризует так:

Отвечая на критику системы СИ в части её применения к электромагнитным явлениям, С. Г. Каршенбойм поясняет, что в критических высказываниях происходит смешение двух различных понятий: система единиц и система физических величин, а также отмечает, что в действительности бо́льшая часть критики относится именно к системе величин. Кроме того, он показывает, что проблема избыточности описания электромагнитных явлений в вакууме возникла не в связи с системой СИ, а в результате исторического процесса — как проблема эфира и нековариантности подхода к описанию. В завершение С. Г. Каршенбойм обосновывает и высказывает убеждённость в том, что системы СИ и СГС в качестве конкурирующих можно рассматривать лишь при фиксированном значении электрической постоянной ε{\displaystyle \varepsilon _{0}}, а при измеряемой величине ε{\displaystyle \varepsilon _{0}} выбор в пользу СИ станет безальтернативным. Поясним здесь, что в силу действовавшего на момент публикации указанных аргументов определения единицы ампер электрическая постоянная имела фиксированное точное значение, но в настоящее время, после вступления в силу нового определения ампера, она стала измеряемой величиной и приобрела погрешность, как и магнитная постоянная.

В то же время сам С. Г. Каршенбойм критикует введение в СИ единицы силы света, канделы, полагая её излишней для системы физических величин ввиду того, что в определение канделы входят нефизические факторы, привнесённые из биологии и медицины.

Ссылка на основную публикацию