Перевод беззнакового числа в знаковое

Перевод беззнакового числа в знаковое

Целые числа являются простейшими числовыми данными, с которыми оперирует ЭВМ. Для целых чисел существуют два представления: беззнаковое (только для неотрицательных целых чисел) и со знаком. Очевидно, что отрицательные числа можно представлять только в знаковом виде. Целые числа в компьютере хранятся в формате с фиксированной запятой.

Представление целых чисел в беззнаковых целых типах.

Представление целых чисел в знаковых целых типах.

Прямой код числа.

Дополнительный код числа.


Дополнительный код положительного числа равен прямому коду этого числа. Дополнительный код отрицательного числа m равен 2 k -|m|, где k — количество разрядов в ячейке.
Как уже было сказано, при представлении неотрицательных чисел в беззнаковом формате все разряды ячейки отводятся под само число. Например, запись числа 243=11110011 в одном байте при беззнаковом представлении будет выглядеть следующим образом:

1 1 1 1 0 0 1 1

При представлении целых чисел со знаком старший (левый) разряд отводится под знак числа, и под собственно число остаётся на один разряд меньше. Поэтому, если приведённое выше состояние ячейки рассматривать как запись целого числа со знаком, то для компьютера в этой ячейке записано число -13 (243+13=256=28).
Но если это же отрицательное число записать в ячейку из 16-ти разрядов, то содержимое ячейки будет следующим:

1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1

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

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

Алгоритм получения дополнительного кода отрицательного числа.


Для получения дополнительного k-разрядного кода отрицательного числа необходимо

  1. модуль отрицательного числа представить прямым кодом в k двоичных разрядах;
  2. значение всех бит инвертировать:все нули заменить на единицы, а единицы на нули(таким образом, получается k-разрядный обратный код исходного числа);
  3. к полученному обратному коду прибавить единицу.

Пример:
Получим 8-разрядный дополнительный код числа -52:

Можно заметить, что представление целого числа не очень удобно изображать в двоичной системе, поэтому часто используют шестнадцатеричное представление:

Представление вещественных чисел в компьютере.

Для представления вещественных чисел в современных компьютерах принят способ представления с плавающей запятой. Этот способ представления опирается на нормализованную (экспоненциальную) запись действительных чисел.
Как и для целых чисел, при представлении действительных чисел в компьютере чаще всего используется двоичная система, следовательно, предварительно десятичное число должно быть переведено двоичную систему.

Нормализованная запись числа.


Нормализованная запись отличного от нуля действительного числа — это запись вида a= m*P q , где q — целое число (положительное, отрицательное или ноль), а m — правильная P-ичная дробь, у которой первая цифра после запятой не равна нулю, то есть . При этом m называется мантиссой числа, q — порядком числа.

Примеры:

  1. 3,1415926 = 0, 31415926 * 10 1 ;
  2. 1000=0,1 * 10 4 ;
  3. 0,123456789 = 0,123456789 * 10 0 ;
  4. 0,00001078 = 0,1078 * 8 -4 ; (порядок записан в 10-й системе)
  5. 1000,00012 = 0, 100000012 * 2 4 .

Так как число ноль не может быть записано в нормализованной форме в том виде, в каком она была определена, то считаем, что нормализованная запись нуля в 10-й системе будет такой:
0 = 0,0 * 10 0 .

Нормализованная экспоненциальная запись числа — это запись вида a= m*P q , где q — целое число (положительное, отрицательное или ноль), а m — P-ичная дробь, у которой целая часть состоит из одной цифры. При этом (m-целая часть) называется мантиссой числа, q — порядком числа.

Представление чисел с плавающей запятой.


При представлении чисел с плавающей запятой часть разрядов ячейки отводится для записи порядка числа, остальные разряды — для записи мантиссы. По одному разряду в каждой группе отводится для изображения знака порядка и знака мантиссы. Для того, чтобы не хранить знак порядка, был придуман так называемый смещённый порядок, который рассчитывается по формуле 2 a-1 +ИП, где a — количество разрядов, отводимых под порядок.

Пример:
Если истинный порядок равен -5, тогда смещённый порядок для 4-байтового числа будет равен 127-5=122.

Алгоритм представления числа с плавающей запятой.

  1. Перевести число из p-ичной системы счисления в двоичную;
  2. представить двоичное число в нормализованной экспоненциальной форме;
  3. рассчитать смещённый порядок числа;
  4. разместить знак, порядок и мантиссу в соответствующие разряды сетки.

Пример:
Представить число -25,625 в машинном виде с использованием 4 байтового представления (где 1 бит отводится под знак числа, 8 бит — под смещённый порядок, остальные биты — под мантиссу).

2510=1000112
0,62510=0,1012
-25,62510= -100011,1012
2. -100011,1012 = -1,000111012 * 2 4
3. СП=127+4=131
4.

Можно заметить, что представление действительного числа не очень удобно изображать в двоичной системе, поэтому часто используют шестнадцатеричное представление:


Окончательный ответ: C1CD0000.

Источник

Преобразование типов

Всякий раз, когда в операторе используются два операнда, над одним из них или над обоими производится некоторый род преобразований. Например, short int и long int нельзя складывать напрямую. Вместо этого short int должен быть преобразован в long int , и, затем, два значения могут быть сложены.

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

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

Правила преобразования типов полностью раскрыты в последующих разделах.

Целочисленное расширение

Правило:
char , short int или битовое поле типа int в любой, знаковой или беззнаковой форме, или объект перечислимого типа всегда преобразуются в int . Если тип int недостаточен для хранения всего диапазона преобразуемого объекта, то он конвертируется в unsigned int .

signed или unsigned char всегда конвертируется в signed int без изменения значения.

В Watcom C/16 short int имеет тот же диапазон, что и int , поэтому signed short int конвертируется в signed int , а unsigned short int — в unsigned int без изменения значения.

В Watcom C/32 signed или unsigned short int конвертируется в int без изменения значения.

Это преобразование называется целочисленным расширением.

Преобразования знаковых и беззнаковых целых

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

Если беззнаковое целое конвертируется в более длинный тип (тип с большим диапазоном), то значение не изменится. Если оно преобразуется к типу с меньшим диапазоном и может быть этим меньшим диапазоном представлено, то значение останется без изменения. Если значение не может быть представлено и, если результат имеет знаковый тип, то конечный результат зависит от реализации. Если тип результата — беззнаковый, то результат — целое по модулю (1 + наибольшее беззнаковое число, которое можно хранить в этом более коротком типе).

В Watcom C/16 беззнаковые целые приводятся к более длинным типам заполнением старших битов нулями. Приведение к меньшим типам производится отбрасыванием старшей части большего типа.

Рассмотрим следующие примеры 32-битных величин ( unsigned long int ), которые сконвертированы к 16-битным ( signed short int или unsigned short int ):

long 32-битное
представление
16-битное
представление
signed short unsigned short
65538 0x00010002 0x0002 2 2
100000 0x000186A0 0x86A0 -31072 34464

Правило:
Если знаковое целое конвертируется к беззнаковому такой же или большей длины и значение неотрицательно, то значение остаётся без изменений.

Неотрицательное значение, хранимое в знаковом целом, может быть сконвертировано в эквивалентный или более длинный целый тип без влияния на значение. Отрицательное значение сначала конвертируется в знаковый тип такой же длины, что и результат, а затем к нему добавляется (1 + наибольшее беззнаковое число, которое может быть сохранено в результирующем типе), чтобы сконвертировать его к беззнаковому типу.

В Watcom C/16 знаковые целые приводятся к более длинным типам при помощи расширения знака (старший бит более короткого типа заполняет все старшие биты более длинного). Если более длинный тип — беззнаковый, то расширяемый знаковый бит затем считается беззнаковым значением.

Рассмотрим следующие примеры 16-битных величин ( signed short int ), которые сконвертированы в 32-битные ( signed long int и unsigned long int ):

signed short 16-битное
представление
32-битное
представление
signed long unsigned long
-2 0xFFFE 0xFFFFFFFE -2 4294967294
32766 0x7FFE 0x00007FFE 32766 32766

Правило:
Если знаковое целое конвертируется в более длинное знаковое целое, то значение не изменится.

Правило:
Если знаковое целое конвертируется в более короткий тип, то результат зависит от реализации.

В Watcom C/16 знаковые целые конвертируются в более короткий тип с сохранением младшей (менее значащей) части большего типа.

Преобразования типов с плавающей точкой в целые

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

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

Преобразования целых в типы с плавающей точкой

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

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

FLT_ROUND Округление
-1 неопределённое
0 в сторону нуля
1 до ближайшего числа
2 в сторону плюс бесконечности
3 в сторону минус бесконечности

Компиляторы Watcom C/16 и C/32 будут округлять до ближайшего числа. (Значение FLT_ROUNDS равно 1.)

Правило:
Если значение с плавающей точкой конвертируется в больший тип с плавающей точкой ( float в double , float в long double , или double в long double ), то значение не изменится.

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

Компиляторы Watcom C/16 и C/32 будут округлять до ближайшего числа. (Значение FLT_ROUNDS равно 1.)

Арифметические преобразования

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

long double
double
float
unsigned long
long
unsigned int
int

Помните, что любой тип, меньший int подвергается целочисленному расширению, чтобы привести его к int .

Следующая таблица демонстрирует типы результата при сложении различных типов:

Оператор Тип результата
signed char + signed char signed int
unsigned char + signed int signed int
signed int + signed int signed int
signed int + unsigned int unsigned int
unsigned int + signed long signed long
signed int + unsigned long unsigned long
signed char + float float
signed long + double double
float + double double
float + long double long double

Преобразование аргументов по умолчанию

Когда производится вызов функции, компилятор C проверяет, определена ли уже функция, либо есть ли у неё прототип. Если это так, то аргументы функции преобразуются к указанным типам. Если нет, то аргументы преобразуются как показано ниже:

  • все целочисленные аргументы подвергаются целочисленному расширению и
  • все аргументы типа float расширяются до double .

Если определение функции не содержит параметров, совпадающих с расширенными типами, то поведение не определено.

Источник

Оцените статью
( Пока оценок нет )
Поделиться с друзьями
Uchenik.top - научные работы и подготовка
0 0 голоса
Article Rating
Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии