Сайт о телевидении

Сайт о телевидении

» » Как представить число двоичном виде. Типы данных. Формы представления чисел. Булевы типы

Как представить число двоичном виде. Типы данных. Формы представления чисел. Булевы типы

Любому, кто хоть раз задумывался в жизни о том, чтобы стать "айтишником" или системным администратором, да и просто связать судьбу с знание о том, как происходит представление чисел в абсолютно необходимо. Ведь именно на этом основываются языки программирования низкого уровня, такие как Assembler. Поэтому сегодня мы рассмотрим представление чисел в компьютере и их размещение в ячейках памяти.

Система счисления

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

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

Итак, для того чтобы перевести число в двоичную систему счисления, нужно взять выбранное нами значение и поделить его на 2. После этого мы получим результат и остаток (0 или 1). Результат опять делим 2 и запоминаем остаток. Данную процедуру нужно повторять до тех пор, пока в итоге также не окажется 0 или 1. Затем записываем конечное значение и остатки в обратном порядке, как мы их получали.

Именно так и происходит представление чисел в компьютере. Любое число записывается в двоичной форме, а потом занимает ячейку памяти.

Память

Как вам должно быть уже известно, минимальная единица измерения информации составляет 1 бит. Как мы уже выяснили, представление чисел в компьютере происходит в двоичном формате. Таким образом, каждый бит памяти будет занят одним значением - 1 или 0.

Для хранения используются ячейки. Каждая такая единица содержит до 8 бит информации. Поэтому можно сделать вывод, что минимальное значение в каждом отрезке памяти может составлять 1 байт или быть восьмизначным двоичным числом.

Целые

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

Начнем мы с самого простого варианта, коим является представление целых чисел в компьютере. Память ПК отводит под этот процесс до смешного малое количество ячеек - всего одну. Таким образом, максимум в одном слоте могут быть значения от 0 до 11111111. Давайте переведём максимальное число в привычную нам форму записи.
Х = 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0 = 1 × 2 8 - 1 = 255.

Теперь мы видим, что в одной ячейке памяти может располагаться значение от 0 до 255. Однако это относится исключительно к целым неотрицательным числам. Если же компьютеру понадобится записать отрицательное значение, всё пройдет немного по-другому.

Отрицательные числа

Теперь давайте посмотрим, как происходит представление чисел в компьютере, если они являются отрицательными. Для размещения значения, которое меньше нуля, отводится две ячейки памяти, или 16 бит информации. При этом 15 уходят под само число, а первый (крайний левый) бит отдается под соответствующий знак.

Если цифра отрицательная, то записывается "1", если положительная, то "0". Для простоты запоминания можно провести такую аналогию: если знак есть, то ставим 1, если его нет, то ничего (0).

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

Для того чтобы разместить в 2 ячейках памяти значение больше нуля или равное ему, используется так называемый прямой код. Данная операция производится так же, как и было описано, а максимальное А = 32766, если использовать Сразу хочется отметить, что в данном случае "0" относится к положительным.

Примеры

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

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

  1. Сначала записывается модуль отрицательного числа в двоичном счислении. То есть компьютер запоминает аналогичное, но положительное значение.
  2. Затем проводится инвертирование каждого бита памяти. Для этого все единицы заменяются нулями и наоборот.
  3. Прибавляем "1" к полученному результату. Это и будет дополнительный код.

Приведем наглядный пример. Пусть у нас есть число Х = - 131. Сначала получаем его модуль |Х|= 131. Затем переводим в двоичную систему и записываем в 16 ячеек. Получим Х = 0000000010000011. После инвертирования Х=1111111101111100. Добавляем к нему "1" и получаем обратный код Х=1111111101111101. Для записи в 16-битную ячейку памяти минимальным числом является Х = - (2 15) = - 32767.

Длинные целые

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

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

Х мах =2 147 483 647.

Х min =- 2 147 483 648.

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

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

Плавающая запятая

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

Любое число может быть представлено в следующей форме Х = m * р п. Где m - это мантисса числа, р - основание системы счисления и п - порядок числа.

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

Пусть нам дано число 666,66. Приведём его к экспоненциальной форме. Получится Х = 0,66666 * 10 3 . Р = 10 и п = 3.

На хранение значений с плавающей запятой обычно выделяется 4 или 8 байт (32 или 64 бита). В первом случае это называется числом обычной точности, а во втором - двойной точности.

Из 4 байт, выделенных под хранение цифр, 1 (8 разрядов) отдается под данные о порядке и его знаке, а 3 байта (24 разряда) уходят на хранение мантиссы и её знака по тем же принципам, что и для целочисленных значений. Зная это, мы можем провести нехитрые расчеты.

Максимальное значение п = 1111111 2 = 127 10 . Исходя из него, мы можем получить максимальный размер числа, которое может храниться в памяти компьютера. Х=2 127 . Теперь мы можем вычислить максимально возможную мантиссу. Она будет равна 2 23 - 1 ≥ 2 23 = 2 (10 × 2,3) ≥ 1000 2,3 = 10 (3 × 2,3) ≥ 10 7 . В итоге, мы получили приближенное значение.

Если теперь мы объединим оба расчета, то получим значение, которое может быть записано без потерь в 4 байта памяти. Оно будет равно Х = 1,701411 * 10 38 . Остальные цифры были отброшены, поскольку именно такую точность позволяет иметь данный способ записи.

Двойная точность

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

П = 1111111111 2 = 1023 10 .

М = 2 52 -1 = 2 (10*5.2) = 1000 5.2 = 10 15.6 . Округляем в большую сторону и получаем максимальное число Х = 2 1023 с точностью до "м".

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

В далекие времена, для IT-индустрии это 70-е годы прошлого века, ученые-математики (так раньше назывались программисты) сражались как Дон-Кихоты в неравном бою с компьютерами, которые тогда были размером с маленькие ветряные мельницы. Задачи ставились серьезные: поиск вражеских подлодок в океане по снимкам с орбиты, расчет баллистики ракет дальнего действия, и прочее. Для их решения компьютер должен оперировать действительными числами, которых, как известно, континуум, тогда как память конечна. Поэтому приходится отображать этот континуум на конечное множество нулей и единиц. В поисках компромисса между скоростью, размером и точностью представления ученые предложили числа с плавающей запятой (или плавающей точкой, если по-буржуйски).

Арифметика с плавающей запятой почему-то считается экзотической областью компьютерных наук, учитывая, что соответствующие типы данных присутствуют в каждом языке программирования. Я сам, если честно, никогда не придавал особого значения компьютерной арифметике, пока решая одну и ту же задачу на CPU и GPU получил разный результат. Оказалось, что в потайных углах этой области скрываются очень любопытные и странные явления: некоммутативность и неассоциативность арифметических операций, ноль со знаком, разность неравных чисел дает ноль, и прочее. Корни этого айсберга уходят глубоко в математику, а я под катом постараюсь обрисовать лишь то, что лежит на поверхности.

1. Основы

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

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

Математически это записывается так:

(-1) s × M × B E , где s - знак, B-основание, E - порядок, а M - мантисса.

Основание определяет систему счисления разрядов. Математически доказано, что числа с плавающей запятой с базой B=2 (двоичное представление) наиболее устойчивы к ошибкам округления, поэтому на практике встречаются только базы 2 и, реже, 10. Для дальнейшего изложения будем всегда полагать B=2, и формула числа с плавающей запятой будет иметь вид:

(-1) s × M × 2 E

Что такое мантисса и порядок? Мантисса – это целое число фиксированной длины, которое представляет старшие разряды действительного числа. Допустим наша мантисса состоит из трех бит (|M|=3). Возьмем, например, число «5», которое в двоичной системе будет равно 101 2 . Старший бит соответствует 2 2 =4, средний (который у нас равен нулю) 2 1 =2, а младший 2 0 =1. Порядок – это степень базы (двойки) старшего разряда. В нашем случае E=2. Такие числа удобно записывать в так называемом «научном» стандартном виде, например «1.01e+2». Сразу видно, что мантисса состоит из трех знаков, а порядок равен двум.

Допустим мы хотим получить дробное число, используя те же 3 бита мантиссы. Мы можем это сделать, если возьмем, скажем, E=1. Тогда наше число будет равно

1,01e+1 = 1×2 1 +0×2 0 +1×2 -1 =2+0,5=2,5

Здесь, поскольку E=1, степень двойки первого разряда (который идет перед запятой), равна «1». Два других разряда, расположенных правее (после запятой), обеспечивают вклад 2 E-1 и 2 E-2 (2 0 и 2 -1 соответственно). Очевидно, что регулируя E одно и то же число можно представить по-разному. Рассмотрим пример с длиной мантиссы |M|=4. Число «2» можно представить в следующем виде:

2 = 10 (в двоичной системе) = 1.000e+1 = 0.100e+2 = 0.010e+3. (E=1, E=2, E=3 соответственно)

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

Это экономит один бит, так как неявную единицу не нужно хранить в памяти, и обеспечивает уникальность представления числа. В нашем примере «2» имеет единственное нормализованное представление («1.000e+1»), а мантисса хранится в памяти как «000», т.к. старшая единица подразумевается неявно. Но в нормализованном представлении чисел возникает новая проблема - в такой форме невозможно представить ноль.

Строго говоря, нормализованное число имеет следующий вид:

(-1) s × 1.M × 2 E .

Качество решения задач во многом зависит от выбора представления чисел с плавающей запятой. Мы плавно подошли к проблеме стандартизации такого представления.

2. Немного истории

В 60-е и 70-е годы не было единого стандарта представления чисел с плавающей запятой, способов округления, арифметических операций. В результате программы были крайне не портабельны. Но еще большей проблемой было то, что у разных компьютеров были свои «странности» и их нужно было знать и учитывать в программе. Например, разница двух не равных чисел возвращала ноль. В результате выражения «X=Y» и «X-Y=0» вступали в противоречие. Умельцы обходили эту проблему очень хитрыми трюками, например, делали присваивание «X=(X-X)+X» перед операциями умножения и деления, чтобы избежать проблем.

Инициатива создать единый стандарт для представления чисел с плавающей запятой подозрительно совпала с попытками в 1976 году компанией Intel разработать «лучшую» арифметику для новых сопроцессоров к 8086 и i432. За разработку взялись ученые киты в этой области, проф. Джон Палмер и Уильям Кэхэн. Последний в своем интервью высказал мнение, что серьезность, с которой Intel разрабатывала свою арифметику, заставила другие компании объединиться и начать процесс стандартизации.

Все были настроены серьезно, ведь очень выгодно продвинуть свою архитектуру и сделать ее стандартной. Свои предложения представили компании DEC, National Superconductor, Zilog, Motorola. Производители мейнфреймов Cray и IBM наблюдали со стороны. Компания Intel, разумеется, тоже представила свою новую арифметику. Авторами предложенной спецификации стали Уильям Кэхэн, Джероми Кунен и Гарольд Стоун и их предложение сразу прозвали «K-C-S».

Практически сразу же были отброшены все предложения, кроме двух: VAX от DEC и «K-C-S» от Intel. Спецификация VAX была значительно проще, уже была реализована в компьютерах PDP-11, и было понятно, как на ней получить максимальную производительность. С другой стороны в «K-C-S» содержалось много полезной функциональности, такой как «специальные» и «денормализованные» числа (подробности ниже).

В «K-C-S» все арифметические алгоритмы заданы строго и требуется, чтобы в реализации результат с ними совпадал. Это позволяет выводить строгие выкладки в рамках этой спецификации. Если раньше математик решал задачу численными методами и доказывал свойства решения, не было никакой гарантии, что эти свойства сохранятся в программе. Строгость арифметики «K-C-S» сделала возможным доказательство теорем, опираясь на арифметику с плавающей запятой.

Компания DEC сделала все, чтобы ее спецификацию сделали стандартом. Она даже заручилась поддержкой некоторых авторитетных ученых в том, что арифметика «K-C-S» в принципе не может достигнуть такой же производительности, как у DEC. Ирония в том, что Intel знала, как сделать свою спецификацию такой же производительной, но эти хитрости были коммерческой тайной. Если бы Intel не уступила и не открыла часть секретов, она бы не смогла сдержать натиск DEC.

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

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

Разработчики «K-C-S» победили и теперь их детище воплотилось в стандарт IEEE754. Числа с плавающей запятой в нем представлены в виде знака (s), мантиссы (M) и порядка (E) следующим образом:

(-1) s × 1.M × 2 E

Замечание. В новом стандарте IEE754-2008 кроме чисел с основанием 2 присутствуют числа с основанием 10, так называемые десятичные (decimal) числа с плавающей запятой.

Чтобы не загромождать читателя чрезмерной информацией, которую можно найти в Википедии , рассмотрим только один тип данных, с одинарной точностью (float). Числа с половинной, двойной и расширенной точностью обладают теми же особенностями, но имеют другой диапазон порядка и мантиссы. В числах одинарной точности (float/single) порядок состоит из 8 бит, а мантисса – из 23. Эффективный порядок определяется как E-127. Например, число 0,15625 будет записано в памяти как

Рисунок взят из Википедии

В этом примере:

  • Знак s=0 (положительное число)
  • Порядок E=01111100 2 -127 10 = -3
  • Мантисса M = 1.01 2 (первая единица не явная)
  • В результате наше число F = 1.01 2 e-3 = 2 -3 +2 -5 = 0,125 + 0,03125 = 0,15625

Чуть более подробное объяснение

Здесь мы имеем дело с двоичным представлением числа «101» со сдвигом запятой на несколько разрядов влево. 1,01 - это двоичное представление, означающее 1×2 0 + 0×2 -1 + 1×2 -2 . Сдвинув запятую на три позиции влево получим 1,01e-3 = 1×2 -3 + 0×2 -4 + 1×2 -5 = 1×0,125 + 0×0,0625 + 1×0,03125 = 0,125 + 0,03125 = 0,15625.

3.1 Специальные числа: ноль, бесконечность и неопределенность
В IEEE754 число «0» представляется значением с порядком, равным E=E min -1 (для single это -127) и нулевой мантиссой. Введение нуля как самостоятельного числа (т.к. в нормализованном представлении нельзя представить ноль) позволило избежать многих странностей в арифметике. И хоть операции с нулем нужно обрабатывать отдельно, обычно они выполняются быстрее, чем с обычными числами.

Также в IEEE754 предусмотрено представление для специальных чисел, работа с которыми вызывает исключение. К таким числам относится бесконечность (±∞) и неопределенность (NaN). Эти числа позволяет вернуть адекватное значение при переполнении. Бесконечности представлены как числа с порядком E=E max +1 и нулевой мантиссой. Получить бесконечность можно при переполнении и при делении ненулевого числа на ноль. Бесконечность при делении разработчики определили исходя из существования пределов, когда делимое и делитель стремиться к какому-то числу. Соответственно, c/0==±∞ (например, 3/0=+∞, а -3/0=-∞), так как если делимое стремиться к константе, а делитель к нулю, предел равен бесконечности. При 0/0 предел не существует, поэтому результатом будет неопределенность.

Неопределенность или NaN (от not a number) – это представление, придуманное для того, чтобы арифметическая операция могла всегда вернуть какое-то не бессмысленное значение. В IEEE754 NaN представлен как число, в котором E=E max +1, а мантисса не нулевая. Любая операция с NaN возвращает NaN. При желании в мантиссу можно записывать информацию, которую программа сможет интерпретировать. Стандартом это не оговорено и мантисса чаще всего игнорируется.

Как можно получить NaN? Одним из следующих способов:

  • ∞+(- ∞)
  • 0 × ∞
  • 0/0, ∞/∞
  • sqrt(x), где x<0
По определению NaN ≠ NaN, поэтому, для проверки значения переменной нужно просто сравнить ее с собой.
Зачем нулю знак (или +0 vs -0)
Любознательный читатель вероятно уже замелил заметил, что в описанном представлении чисел с плавающей запятой существует два нуля, которые отличаются только знаком. Так, 3·(+0)=+0, а 3·(-0)=-0. Но при сравнении +0=-0. В стандарте знак сохранили умышленно, чтобы выражения, которые в результате переполнения или потери значимости превращаются в бесконечность или в ноль, при умножении и делении все же могли представить максимально корректный результат. Например, если бы у нуля не было знака, выражение 1/(1/x)=x не выполнялось бы верно при x=±∞, так как 1/∞ и 1/-∞ равны 0.

Еще один пример:
(+∞/0) + ∞ = +∞, тогда как (+∞/-0) +∞ = NaN

Чем бесконечность в данном случае лучше, чем NaN? Тем, что если в арифметическом выражении появился NaN, результатом всего выражения всегда будет NaN. Если же в выражении встретилась бесконечность, то результатом может быть ноль, бесконечность или обычное число с плавающей запятой. Например, 1/∞=0.

3.3 Денормализованные числа
Что такое субнормальные денормализованные (subnormal) числа рассмотрим на простом примере. Пусть имеем нормализованное представление с длиной мантиссы |M|=2 бита (+ один бит нормализации) и диапазоном значений порядка -1≤E≤2. В этом случае получим 16 чисел:

Крупными штрихами показаны числа с мантиссой, равной 1,00. Видно, что расстояние от нуля до ближайшего числа (0 - 0,5) больше, чем от этого числа к следующему (0,5 - 0,625). Это значит, что разница двух любых чисел от 0,5 до 1 даст 0, даже если эти числа не равны. Что еще хуже, в пропасть между 0,5 и 0 попадает разница чисел, больших 1. Например, «1,5-1,25=0» (см. картинку).

В «околонулевую яму» подпадает не каждая программа. Согласно статистике 70-х годов в среднем каждый компьютер сталкивался с такой проблемой один раз в месяц. Учитывая, что компьютеры приобретали массовость, разработчики «K-C-S» посчитали эту проблему достаточно серьезной, чтобы решать ее на аппаратном уровне. Предложенное ими решение состояло в следующем. Мы знаем, что при E=E min -1 (для float это «-127») и нулевой мантиссе число считается равным нулю. Если же мантисса не нулевая, то число считается не нулевым, его порядок полагается E=E min , причем неявный старший бит мантиссы полагается равным нулю. Такие числа называются денормализованными .

Строго говодя, числа с плавающей запятой теперь имеют вид:

(-1) s × 1.M × 2 E , если E min ≤E≤E max (нормализованные числа)

(-1) s × 0.M × 2 Emin , если E=E min -1. (денормализованные числа)

Вернемся к примеру. Наш E min =-1. Введем новое значение порядка, E=-2, при котором числа являются денормализованными. В результате получаем новое представление чисел:

Интервал от 0 до 0,5 заполняют денормализованные числа, что дает возможность не проваливаться в 0 рассмотренных выше примерах (0,5-0,25 и 1,5-1,25). Это сделало представление более устойчиво к ошибкам округления для чисел, близких к нулю.

Но роскошь использования денормализованного представления чисел в процессоре не дается бесплатно. Из-за того, что такие числа нужно обрабатывать по-другому во всех арифметических операциях, трудно сделать работу в такой арифметике эффективной. Это накладывает дополнительные сложности при реализации АЛУ в процессоре. И хоть денормализованные числа очень полезны, они не являются панацеей и за округлением до нуля все равно нужно следить. Поэтому эта функциональность стала камнем преткновения при разработке стандарта и встретила самое сильное сопротивление.

3.4 Очередность чисел в IEEE754
Одна из удивительных особенностей представления чисел в формате IEEE754 состоит в том, что порядок и мантисса расположены друг за другом таким образом, что вместе образуют последовательность целых чисел {n} для которых выполняется:

N

Поэтому если взять положительное число с плавающей запятой, преобразовать его к целому, прибавить «1», мы получим следующее число, которое представимо в этой арифметике. На Си это можно сделать так:

Float a=0.5; int n = *((int*) &a); float b = *((float*) &(++n)); printf("После %e следующее число: %e, разница (%e)\n", a, b, b-a);
Этот код будет работать только на архитектуре с 32-битным int.

4. Подводные камни в арифметике с плавающей запятой

Теперь – к практике. Рассмотрим особенности арифметики с плавающей запятой, к которым нужно проявить особую осторожность при программировании.
4.1 Округление
С ошибками из-за погрешностей округления в современной арифметике с плавающей запятой встретиться сложно, особенно если использовать двойную точность. Правило округления в стандарте IEEE754 говорит о том, что результат любой арифметической операции должен быть таким, как если бы он был выполнен над точными значениями и округлен до ближайшего числа, представимого в этом формате. Это требует от АЛУ дополнительных усилий и некоторые опции компилятора (такие как «-ffast-math» в gcc) могут отключить такое поведение. Особенности округления в IEEE754:
  • Округление до ближайшего в стандарте сделано не так как мы привыкли. Математически показано, что если 0,5 округлять до 1 (в большую сторону), то существует набор операций, при которых ошибка округления будет возрастать до бесконечности. Поэтому в IEEE754 применяется правило округления до четного. Так, 12,5 будет округлено до 12, а 13,5 – до 14.
  • Самая опасная операция с точки зрения округления в арифметике с плавающей запятой - это вычитание. При вычитании близких чисел значимые разряды могут потеряться, что
    может в разы увеличить относительную погрешность.
  • Для многих широко распространенных математических формул математики разработали специальную форму, которая позволяет значительно уменьшить погрешность при округлении. Например, расчет формулы «x 2 -y 2 » лучше вычислять используя формулу «(x-y)(x+y)».
4.2 Неассоциативность арифметических операций
В арифметике с плавающей запятой правило (a*b)*c = a*(b*c) не выполняется для любых арифметических операций. Например,

(10 20 +1)-10 20 =0 ≠ (10 20 -10 20)+1=1

Допустим у нас есть программа суммирования чисел.

Double s = 0.0; for (int i=0; i Некоторые компиляторы по умолчанию могут переписать код для использования нескольких АЛУ одновременно (будем считать, что n делится на 2):

Double sa, s; sa=sa=0.0; for (int i=0; i Так как операции суммирования не ассоциативны, эти две программы могут выдать различный результат.

4.3 Числовые константы
Помните, что не все десятичные числа имеют двоичное представление с плавающей запятой. Например, число «0,2» будет представлено как «0,200000003» в одинарной точности. Соответственно, «0,2 + 0,2 ≈ 0,4». Абсолютная погрешность в отдельном
случае может и не высока, но если использовать такую константу в цикле, можем получить накопленную погрешность.
4.4 Выбор минимума из двух значений
Допустим из двух значений нам нужно выбрать минимальное. В Си это можно сделать одним из следующих способов:
  1. x < y? x: y
  2. x <= y? x: y
  3. x > y? y: x
  4. x >= y? y: x
Часто компилятор считает их эквивалентными и всегда использует первый вариант, так как он выполняется за одну инструкцию процессора. Но если мы учтем ±0 и NaN, эти операции никак не эквивалентны:
x y x < y? x: y x <= y? x: y x > y? y: x x >= y? y: x
+0 -0 -0 +0 +0 -0
NaN 1 1 1 NaN NaN
4.5 Сравнение чисел
Очень распространенная ошибка при работе с float-ами возникает при проверке на равенство. Например,

Float fValue = 0.2; if (fValue == 0.2) DoStuff();
Ошибка здесь, во-первых, в том, что 0,2 не имеет точного двоичного представления, а во-вторых 0,2 – это константа двойной точности, а переменная fValue – одинарной, и никакой гарантии о поведении этого сравнения нет.

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

If (fabs(fValue – fExpected) < 0.0001) DoStuff(); // fValue=fExpected?

Недостаток такого подхода в том, что погрешность представления числа увеличивается с ростом самого этого числа. Так, если программа ожидает «10000», то приведенное равенство не будет выполняться для ближайшего соседнего числа (10000,000977). Это особенно актуально, если в программе имеется преобразование из одинарной точности в двойную.

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

Bool AlmostEqual2sComplement(float A, float B, int maxUlps) { // maxUlps не должен быть отрицательным и не слишком большим, чтобы // NaN не был равен ни одному числу assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); int aInt = *(int*)&A; // Уберем знак в aInt, если есть, чтобы получить правильно упорядоченную последовательность if (aInt < 0) aInt = 0x80000000 - aInt; //aInt &= 0x7fffffff; //(см. комментарий пользователя Vayun) // Аналогично для bInt int bInt = *(int*)&B; if (bInt < 0) bInt = 0x80000000 - bInt; /*aInt &= 0x7fffffff;*/ unsigned int intDiff = abs(aInt - bInt); /*(см. комментарий пользователя Vayun)*/ if (intDiff <= maxUlps) return true; return false; }

В этой программе maxUlps (от Units-In-Last-Place) – это максимальное количество чисел с плавающей запятой, которое может лежать между проверяемым и ожидаемым значением. Другой смысл этой переменной – это количество двоичных разрядов (начиная с младшего) в сравниваемых числах разрешается упустить. Например, maxUlps=16, означает, что младшие 4 бита (log 2 16) могут не совпадать, а числа все равно будут считаться равными. При этом, при сравнении с числом 10000 абсолютная погрешность будет равна 0,0146, а при сравнении с 0.001, погрешность будет менее 0.00000001 (10 -8).

5. Проверка полноты поддержки IEE754

Думаете, что если процессоры полностью соответствуют стандарту IEEE754, то любая программа, использующая стандартные типы данных (такие как float/double в Си), будет выдавать один и тот же результат на разных компьютерах? Ошибаетесь. На портабельность и соответствие стандарту влияет компилятор и опции оптимизации. Уильям Кэхэн написал программу на Си (есть версия и для Фортрана), которая позволяет проверить удовлетворяет ли связка «архитектура+компилятор+опции» IEEE754. Называется она «Floating point paranoia» и ее исходные тексты доступны для скачивания . Аналогичная программа доступна для GPU . Так, например, компилятор Intel (icc) по умолчанию использует «расслабленную» модель IEEE754, и в результате не все тесты выполняются. Опция «-fp-model precise» позволяет компилировать программу с точным соответствием стандарту. В компиляторе GCC есть опция «-ffast-math», использование которой приводит к несоответствию IEEE754.

Заключение

Напоследок поучительная история. Когда я работал над тестовым проектом на GPU, у меня была последовательная и параллельная версия одной программы. Сравнив время выполнения, я был очень обрадован, так как получил ускорение в 300 раз. Но позже оказалось, что вычисления на GPU «разваливались» и обращались в NaN, а работа с ними в GPU была быстрее, чем с обычными числами. Интересно было другое - одна и та же программа на эмуляторе GPU (на CPU) выдавала корректный результат, а на самом GPU – нет. Позже оказалось, что проблема была в том, что этот GPU не поддерживал полностью стандарт IEEE754 и прямой подход не сработал.

Сейчас арифметика с плавающей запятой почти совершенна. Практически всегда наивный подход сработает, и программа, не учитывающая все ее особенности, выдаст правильный результат, а описанные подводные камни касаются только экзотических случаев. Но нужно всегда оставаться бдительным: в таком вопросе как компьютерная математика легко наступить на грабли.
! Добавить метки

Инструкция

Если в виде дроби надо представить целое число , то используйте в качестве знаменателя единицу, а исходное значение ставьте в числитель. Такая форма записи называться неправильной обыкновенной дробью, так как модуль ее числителя больше модуля знаменателя. Например, число 74 можно записать, как 74/1, а число -12 - как -12/1. При необходимости вы можете числитель и знаменатель в одинаковое количество раз - значение дроби в этом случае по-прежнему будет соответствовать исходному числу. Например, 74=74/1=222/3 или -12=-12/1=-84/7.

Если исходное число представлено в формате десятичной дроби , то его целую часть оставьте без изменений, а разделительную запятую замените пробелом. Дробную часть поставьте в числитель, а в качестве знаменателя используйте десятку, возведенную в степень с показателем, равным количеству знаков в дробной исходного числа. Полученную в результате дробную часть можно сократить, разделив числитель и знаменатель на одинаковое число . Например, десятичной дроби 7,625 будет соответствовать обыкновенная дробь 7 625/1000, которая после сокращения примет значение 7 5/8. Такая форма записи обыкновенной дроби смешанной. При необходимости ее можно привести к неправильному обыкновенному виду, умножив целую часть на знаменатель и прибавив результат к числителю: 7,625 = 7 625/1000 = 7 5/8 = 61/8.

Если исходная десятичная дробь является и периодической, то используйте, например, систему уравнений для вычисления ее эквивалента в формате дроби обыкновенной. Скажем, если исходная дробь равна 3,5(3), то можно тождество: 100*x-10*x=100*3,5(3)-10*3,5(3). Из него можно вывести равенство 90*x=318, а , что искомая дробь будет равна 318/90, что после сокращения даст обыкновенную дробь 3 24/45.

Источники:

  • Можно Ли Число 450 000 Представить Как Произведение 2 Чисел?

В быту чаще всего встречаются не натуральные числа: 1, 2, 3, 4 и т.д. (5 кг. картофеля), а дробные, нецелые числа (5,4 кг лука). Большинство из них представлены в виде десятичных дробей. Но десятичную дробь представить в виде дроби достаточно просто.

Инструкция

Например, дано число "0,12". Если не эту дробь и представить ее так, как есть, то выглядеть она будет так: 12/100 ("двенадцать "). Чтобы избавиться от сотни в , нужно и числитель, и знаменатель поделить на число, которое делит их числа. Это число 4. Тогда, поделив числитель и знаменатель, получается число: 3/25.

Если рассматривать более бытовую , то часто на ценнике у видно, что вес его составляет, к примеру, 0,478 кг или пр. Такое число тоже легко представить в виде дроби :
478/1000 = 239/500. Дробь эта достаточно некрасивая, и если бы была возможность, то эту десятичную дробь можно было бы сокращать и далее. И все тем же методом: подбора числа, которое делит как числитель, так и знаменатель. Это число наибольшим общим множителем. "Наибольшим" множитель потому, что гораздо удобнее и числитель, и знаменатель сразу поделить на 4 (как в первом примере), чем делить дважды на 2.

Видео по теме

Десятичная дробь - разновидность дроби , у которой в знаменателе есть "круглое" число: 10, 100, 1000 и т.д., Например, дробь 5/10 имеет десятичную запись 0,5. Исходя из этого принципа, дробь можно представить в виде десятичной дроби .

Инструкция

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

Вам понадобится

  • Калькулятор

Инструкция

Для представления десятичного числа в виде обыкновенной дроби нужно сначала посмотреть, каким оно является - или вещественным. Целое число не имеет запятой вовсе, или после запятой стоит ноль (или много нулей, что одно и тоже). Если же после запятой есть некоторые числа, то данное число относится к вещественным. Целое число очень легко представить в виде дроби: в числитель идет само число , а в знаменатель - . С десятичной почти так же, только будем умножать обе часть дроби на десять до тех пор, пока не избавимся от запятой в числителе.

Представление чисел

Числа в математике

Число-важнейшее понятие математики, которое складывалось и развивалось в течение длительного периода истории человечества. Люди начали работать с числами еще с первобытных времен. Первоначально человек оперировал лишь целыми положительными числами, которые называются натуральными числами: 1, 2, 3, 4, … Долго существовало мнение о том, что есть самое большое число, “боле сего несть человеческому уму разумевати” (так писали в старославянских математических трактатах).

Развитие математической науки привело к выводу, что самого большого числа нет. С математической точки зрения ряд натуральных чисел бесконечен, т.е. неограничен. С появлением в математике понятия отрицательного числа (Р.Декарт, XVII век в Европе; в Индии значительно раньше) оказалось, что множество целых чисел неограниченно как “слева”, так и “справа”. Математическое множество целых чисел дискретно и неограниченно (бесконечно).

Понятие вещественного (или действительного) числа в математику ввел Исаак Ньютон в XVIII веке. С математической точки зрения множество вещественных чисел бесконечно и непрерывно . Оно включает в себя множество целых чисел и еще бесконечное множество нецелых чисел. Между двумя любыми точками на числовой оси лежит бесконечное множество вещественных чисел. С понятием вещественного числа связано представление о непрерывной числовой оси, любой точке которой соответствует вещественное число.

Представление целых чисел

В памяти компьютера числа хранятся в двоичной системе счисления (см. “Системы счисления ” 2). Есть две формы представления целых чисел в компьютере: целые без знака и целые со знаком.

Целые без знака - это множество положительных чисел в диапазоне , где k - это разрядность ячейки памяти, выделяемой под число. Например, если под целое число выделяется ячейка памяти размером в 16 разрядов (2 байта), то самое большое число будет таким:

В десятичной системе счисления это соответствует: 2 16 – 1 = 65 535

Если во всех разрядах ячейки нули, то это будет ноль. Таким образом, в 16-разрядной ячейке помещается 2 16 = 65 536 целых чисел.

Целые числа со знаком - это множество положительных и отрицательных чисел в диапазоне [–2 k –1 , 2 k –1 – 1]. Например, при k = 16 диапазон представления целых чисел: [–32 768, 32 767]. Старший разряд ячейки памяти хранит знак числа: 0 - число положительное, 1 - число отрицательное. Самое большое положительное число 32 767 имеет следующее представление:



Например, десятичное число 255 после перевода в двоичную систему счисления и вписывания в 16-разрядную ячейку памяти будет иметь следующее внутреннее представление:

Отрицательные целые числа представляются в дополнительном коде. Дополнительный код положительного числа N - это такое его двоичное представление, которое при сложении с кодом числа N дает значение 2 k . Здесь k - количество разрядов в ячейке памяти. Например, дополнительный код числа 255 будет следующим:

Это и есть представление отрицательного числа –255. Сложим коды чисел 255 и –255:

Единичка в старшем разряде “выпала” из ячейки, поэтому сумма получилась равной нулю. Но так и должно быть: N + (–N ) = 0. Процессор компьютера операцию вычитания выполняет как сложение с дополнительным кодом вычитаемого числа. При этом переполнение ячейки (выход за предельные значения) не вызывает прерывания выполнения программы. Это обстоятельство программист обязан знать и учитывать!

Формат представления вещественных чисел в компьютере называется форматом с плавающей точкой . Вещественное число R представляется в виде произведения мантиссы m на основание системы счисления n в некоторой целой степени p , которую называют порядком: R = m * n p .

Представление числа в форме с плавающей точкой неоднозначно. Например, для десятичного числа 25,324 справедливы следующие равенства:

25,324 = 2,5324 * 10 1 = 0,0025324 * 10 4 = 2532,4 * 10 –2 и т.п.

Чтобы не было неоднозначности, договорились в ЭВМ использовать нормализованное представление числа в форме с плавающей точкой. Мантисса в нормализованном представлении должна удовлетворять условию: 0,1 n m < 1 n . Иначе говоря, мантисса меньше единицы и первая значащая цифра - не ноль. В некоторых случаях условие нормализации принимают следующим: 1 n m < 10 n .

В памяти компьютера мантисса представляется как целое число, содержащее только значащие цифры (0 целых и запятая не хранятся). Следовательно, внутреннее представление вещественного числа сводится к представлению пары целых чисел: мантиссы и порядка.

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

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

В старшем бите 1-го байта хранится знак числа: 0 обозначает плюс, 1 - минус. Оставшиеся 7 бит первого байта содержат машинный порядок . В следующих трех байтах хранятся значащие цифры мантиссы (24 разряда).

В семи двоичных разрядах помещаются двоичные числа в диапазоне от 0000000 до 1111111. Значит, машинный порядок изменяется в диапазоне от 0 до 127 (в десятичной системе счисления). Всего 128 значений. Порядок, очевидно, может быть как положительным, так и отрицательным. Разумно эти 128 значений разделить поровну между положительными и отрицательными значениями порядка: от –64 до 63.

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

Связь между машинным порядком (Mp) и математическим (p) в рассматриваемом случае выражается формулой: Mp = p + 64.

Полученная формула записана в десятичной системе. В двоичной системе формула имеет вид: Mp 2 = p 2 + 100 0000 2 .

Для записи внутреннего представления вещественного числа необходимо:

1) перевести модуль данного числа в двоичную систему счисления с 24 значащими цифрами,

2) нормализовать двоичное число,

3) найти машинный порядок в двоичной системе счисления,

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

Пример. Записать внутреннее представление числа 250,1875 в форме с плавающей точкой.

Решение

1. Переведем его в двоичную систему счисления с 24 значащими цифрами:

250,1875 10 = 11111010,0011000000000000 2 .

2. Запишем в форме нормализованного двоичного числа с плавающей точкой:

0,111110100011000000000000 Ч 10 2 1000 .

Здесь мантисса, основание системы счисления
(2 10 = 10 2) и порядок (8 10 = 1000 2) записаны в двоичной системе.

3. Вычислим машинный порядок в двоичной системе счисления:

Mp 2 = 1000 + 100 0000 = 100 1000.

4. Запишем представление числа в четырехбайтовой ячейке памяти с учетом знака числа

Шестнадцатеричная форма: 48FA3000.

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

Наименьшее по абсолютной величине число равно нулю. Наибольшее по абсолютной величине число в форме с плавающей точкой - это число с самой большой мантиссой и самым большим порядком.

Для четырехбайтового машинного слова таким числом будет:

0,111111111111111111111111 · 10 2 1111111 .

После перевода в десятичную систему счисления получим:

MAX = (1 – 2 –24) · 2 63 10 19 .

Если при вычислениях с вещественными числами результат выходит за пределы допустимого диапазона, то выполнение программы прерывается. Такое происходит, например, при делении на ноль, или на очень маленькое число, близкое к нулю.

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

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

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

Количество вещественных чисел, точно представимых в памяти компьютера, можно вычислить по формуле : N = 2 t · (U L + 1) + 1. Здесь t - количество двоичных разрядов мантиссы; U - максимальное значение математического порядка; L - минимальное значение порядка. Для рассмотренного выше варианта представления (t = 24, U = 63,
L
= –64) получается: N = 2 146 683 548.

Пример 1. Получить внутреннее представление в формате “со знаком” целого числа 1607 в двухбайтовой ячейке памяти.

Решение

1) Перевести число в двоичную систему счисления: 1607 10 = 11001000111 2 .

2) Дописывая слева нули до 16 разрядов, получим внутреннее представление этого числа в ячейке:

Желательно показать, как для сжатой формы записи этого кода используется шестнадцатеричная форма, которая получается заменой каждой четверки двоичных цифр одной шестнадцатеричной цифрой: 0647 (см. “Системы счисления ” 2).

Более сложной является задача получения внутреннего представления отрицательного целого числа (–N ) - дополнительного кода. Нужно показать ученикам алгоритм этой процедуры:

1) получить внутреннее представление положительного числа N ;

2) получить обратный код этого числа заменой 0 на 1 и 1 на 0;

3) к полученному числу прибавить 1.

Пример 2. Получить внутреннее представление целого отрицательного числа –1607 в двухбайтовой ячейке памяти.

Решение

Полезно показать ученикам, как выглядит внутреннее представление самого маленького отрицательного числа. В двухбайтовой ячейке это –32 768.

1) легко перевести число 32 768 в двоичную систему счисления, поскольку 32 768 = 2 15 . Следовательно, в двоичной системе это:

2) запишем обратный код:

3) прибавим единицу к этому двоичному числу, получим

Единичка в первом бите обозначает знак “минус”. Не нужно думать, что полученный код - это минус ноль. Это –32 768 в форме дополнительного кода. Таковы правила машинного представления целых чисел.

Показав этот пример, предложите ученикам самостоятельно доказать, что при сложении кодов чисел 32 767 + (–32 768) получится код числа –1.

Целые числа могут представляться в компьютере без знака или со знаком.

Целые числа без знака. Целые числа без знака обычно зани­мают в памяти компьютера 1 или 2 байт и принимают в одно­байтовом формате значения от 00000000 2 до 11111111 2 , ав дву­байтовом формате - от 00000000 00000000 2 до 11111111 11111111 2 (табл. 2.2).

Целые числа со знаком. Целые числа со знаком обычно занима­ют в памяти компьютера 1, 2 или 4 байт, при этом самый левый (старший) разряд содержит информацию о знаке числа. Знак « + » кодируется нулем, а «-» - единицей (табл. 2.3).

Рассмотрим особенности записи целых чисел со знаком на примере однобайтового формата, при котором для знака отво­дится один разряд, а для цифр абсолютной величины - семь раз­рядов.

В компьютерной технике применяются три формы записи (ко­дирования) целых чисел со знаком: прямой код, обратный код, дополнительный код. Последние две формы применяются особенно широко, так как позволяют упростить конструкцию арифметико-логического устройства компьютера путем замены разнообразных арифметических операций операцией сложения.

Положительные числа в прямом, обратном и дополнительном кодах изображаются одинаково - двоичными кодами с цифрой 0 в знаковом разряде.

Таблица 2.2 Диапазоны значений целых чисел без знака

Число 1 ,о = 1 2: Число 127 10 = 1111111 2:

0000000 10 1111111

Знак числа «-»| Знак числа «-»

Отрицательные числа в прямом, обратном и дополнительном кодах имеют разное изображение.

Прямой код числа -1: Прямой код числа -127:

1ОООООоТ11111111

Знак числа «+»Знак числа «+»

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

Обратный код получается инвертированием всех цифр дво­ичного кода, абсолютной величины числа, включая разряд знака: нули заменяются единицами, а единицы - нулями.

Примеры.

Число:-1. Число:-127.

Код модуля числа: 00000001 Код модуля числа: 01111111

Обратный код числа: 11111110 Обратный код числа: 10000000

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

Дополнительный код числа -1: Дополнительный код числа -127:

Р

11111110 10000000

11111111 10 0 0 0 0 0 1

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

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

Вещественные числа. Вещественные числа (конечные и беско­нечные десятичные дроби) хранятся и обрабатываются в компь­ютере в формате с плавающей запятой. В этом случае положение запятой в записи числа может изменяться.

Формат чисел с плавающей запятой базируется на экспонен­циальной форме записи, в которой может быть представлено лю­бое число. Так, число А может быть представлено в виде

А = т- q",

где т - мантисса числа; q - основание системы счисления; п - порядок числа.

Для однозначности представления чисел с плавающей запятой используется нормализованная форма, при которой мантисса от­вечает условию

1/я = \т\ < 1.

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

Примеры. Преобразуем числа в экспоненциальную форму с нормализованной мантиссой:

421,637 = 0,421637 10 3 ;

0,000286 = 0,286 10" 4 ;

25,25 = -2,525 10 2 .

Число в форме с плавающей запятой занимает в памяти ком­пьютера 4 (число обычной точности) или 8 (число двойной точ­ности) байт. При записи числа с плавающей запятой выделяют разряды для хранения знака мантиссы, знака порядка, порядка и

мантиссы.

Арифметические операции. При сложении и вычитании чисел в формате с плавающей запятой сначала производится подготови­тельная операция выравнивания порядков. Порядок меньшего (по модулю) числа увеличивается до величины порядка большего (по модулю) числа. Для того чтобы величина числа не изменилась, мантисса уменьшается в такое же число раз (сдвигается в ячейке памяти вправо на число разрядов, равное разности порядков чисел).

После выполнения операции выравнивания одинаковые раз­ряды чисел оказываются расположенными в одних и тех же раз­рядах ячеек памяти. Теперь операции сложения и вычитания чи­сел сводятся к сложению или вычитанию мантисс.

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

Пример. Произвести сложение чисел 0,1 *2 3 и 0,1 2 5 в формате с плавающей запятой.

Произведем выравнивание порядков и сложение мантисс:

+ 0,100 -2 5

При умножении чисел в формате с плавающей запятой поряд­ки складываются, а мантиссы перемножаются. При делении из порядка делимого вычитается порядок делителя, а мантисса де­лимого делится на мантиссу делителя.

Пример. Произвести умножение чисел 0,1 2 3 и 0,1 2 5 в форма­те с плавающей запятой.

После умножения будет получено число 0,01 2 8 , которое пос­ле нормализации примет вид 0,1 2 7 .

2.1.7. Представление других видов информации в компьютере Все виды информации (текстовая, графическая, звуковая, ви­део-) кодируются в последовательности нулей и единиц. Рассмот­рим этот процесс более подробно.

Двоичное кодирование текстовой информации. Традиционно для кодирования одного символа используется количество информа­ции, равное 1 байт, которое составляет 8 бит (2 8 = 256), поэтому можно закодировать 256 различных символов.

Такое число символов вполне достаточно для представления текстовой информации, включая прописные и заглавные буквы русского и латинского алфавита, цифры, знаки, графические сим­волы и т.д.

Кодирование заключается в том, что каждому символу ставит­ся в соответствие уникальный десятичный код от 0 до 255 или соответствующий ему двоичный код от 00000000 до 11111111.

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

В процессе вывода символа на экран компьютера производится обратный процесс - декодирование, т.е. преобразование кода символа в его изображение.

Присвоение символу конкретного кода - это вопрос соглаше­ния, которое фиксируется в кодовой таблице. Первые 33 кода (с О по 32) соответствуют не символам, а операциям (перевод стро­ки, ввод пробела и т.д.).

В качестве международного стандарта принята кодовая таблица ASCII (American Standard Code for Information Interchange) (рис. 2.1, а), кодирующая первую половину символов с числовыми кодами от 32 до 126.

Хронологически одним из первых стандартов кодирования рус­ских букв на компьютерах был КОИ8 («Код обмена информаци­ей, 8-битный»). Эта кодировка с середины 1980-х гг. стала исполь­зоваться в первых русифицированных версиях операционной си­стемы UNIX.

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

Рис. 2.1. Примеры кодировочных таблиц:

а - международная кодировка ASCII; б - кодировка СР1251

Наиболее распространенной в настоящее время является ко­дировка Microsoft Windows, обозначаемая СР1251 (от англ. Code page - кодовая страница) (рис. 2.1, б).

В конце 1990-х гг. появился новый международный стандарт Unicode, который отводит под один символ не 1 байт, а 2 байт, поэтому с его помощью можно закодировать не 256, а 65 536 раз­личных символов. Полная спецификация стандарта Unicode вклю­чает в себя все существующие, вымершие и искусственно создан­ные алфавиты мира, а также множество математических, музы­кальных, химических и прочих символов.

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

Качество изображения определяется разрешающей способно­стью монитора, т. е. числом точек, из которых оно складывается. Чем больше разрешающая способность монитора, т. е. чем больше число строк растра и точек в строке, тем выше качество изобра­жения. В современных персональных компьютерах обычно исполь­зуются четыре основные разрешающие способности экрана: 640 х 480, 800 х 600, 1024 х 768 и 1280 х 1024 точки.

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

Цветное изображение на экране монитора формируется за счет смешивания трех базовых цветов: красного, зеленого и синего. Такая цветовая модель называется RGB-моделью (от англ. Red, Green, Blue - красный, зеленый, синий). Для получения богатой палит-

Таблица 2.4 Глубина цвета и число отображаемых цветов

Таблица 2.5 Формирование цветов при глубине цвета 24 бит

ры цветов базовым цветам могут быть заданы различные интен­сивности, Например, при глубине цвета в 24 бит на каждый из цветов выделяется по 8 бит, т. е. для каждого из цветов возможны 2 8 = 256 уровней интенсивности, заданных двоичными кодами (от минимальной - 00000000 до максимальной - 11111111) (табл. 2.5).

Для того чтобы на экране монитора формировалось изображе­ние, информация о каждой его точке (код цвета, точки) должна храниться в видеопамяти компьютера. Рассчитаем необходимый объем видеопамяти для одного из графических режимов, напри­мер с разрешением 800 х 600 точек и глубиной цве­та 24 бит на точку. Всего точек на экране: 800 600 = 480 000. Не­обходимый объем видеопамяти: 24 бит 480 000 = 11 520 000 бит = = 1 440 000 байт = 1406,25 Кбайт = 1,37 Мбайт.

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

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

Таким образом, непрерывная зависимость амплитуды сигнала от времени A(t) заменяется на диск­ретную последовательность уровней громкости.

Рис. 2.2. Сетка уровней квантования.

Дискретизация - процесс разбивания сигнала на отдельные составпяющие, взятые в. определенные тактовые моменты времени t 0 , I t 2 ,… Р ез четко определенные тактовые интервалы времени / (рис 2.2).

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

д/ 0) = 2; Л(/,) = 5; A(t 2) = 6; A(t 3) = 6; A(U) = 5; A(t 5) = 5; A(t 6) = 6;

A(t 7) = 6; A(h) = 5.

Кодирование - перевод значения уровня квантования в конк­ретный двоичный код, например:

2-0010; 6-0110; 6-0110; 5-0101; 5-0101; 6-ОНО; 6-0110; 5-0101; 4-0100.

Качество передаваемой информации при этом будет зависеть:

От разрядности преобразования, т. е. числа двоичных разря­дов, которые будут использованы при кодировании соответству­ющего уровня;

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

Уровни громкости звука можно рассматривать как набор воз­можных состояний. Следовательно, чем большее число уровней громкости будет выделено в процессе кодирования, тем большее количество информации будет нести значение каждого уровня и тем более качественным будет звучание. Звуковые карты обеспе­чивают, например, 16-битную глубину кодирования звука, обес­печивая 2 16 = 65 536 уровней сигнала.

Кроме того, качество кодирования зависит и от числа точек измерения уровня сигнала за 1 с, т. е. частоты дискретизации (это значение изменяется от 8000 до 48 000).

Принято измерять частоту дискретизации в кГц (килогерцах): 1 кГц - это 1000 измерений в секунду.

Можно оценить информационный объем стереоаудиофайла Длительностью звучания 1 с при высоком качестве звука (16 бит, 48 кГц). Для этого число бит на одну выборку необходимо умно­жить на число выборок в 1 с и умножить на 2 (стереорежим):

16 бит 48 000 -2=1 536 000 бит = 192 000 байт 187,5 Кбайт.

Информационный объем звукового файла длительностью 1 мин Приблизительно равен 11 Мбайт.

Контрольные вопросы

1.Чем отличаются позиционные системы счисления от непозицион­ных?

2.Какое количество информации несет в себе цифра восьмеричного числа?

3.Почему в компьютере используется двоичная система счисления?

4.В чем заключается преимущество экспоненциальной формы числа?

5.Как кодируются символы текста?

6.В чем заключается метод пространственной дискретизации?

7.Переведите в десятичную систему счисления 1110 2 ; 22 8 ; BF l 6 ; 10110 2 ;

135 8 ; 70£ 16 .

8.Переведите десятичные числа в двоичную, восьмеричную и шест-надцатеричную системы счисления: 74,21; 26,11; 125,01; 114,08.

9.Переведите пары чисел в двоичную систему счисления, произведи­те арифметические операции, ответы проверьте: 36 и 4; 75 и 5; 12 и 4; 123 и 3.

10. В какой системе счисления справедливы следующие равенства:

20 + 25= 100; 22+ 44 =110?

11.Десятичное число 59 эквивалентно числу 214 в некоторой другой системе счисления. Найдите основание этой системы.

12.Переведите числа в десятичную систему, а затем проверьте ре­зультаты, выполнив обратные переводы:

14. Перемножьте числа, а затем проверьте результаты, выполнив со­
ответствующие десятичные умножения:

101101 2 101 2 111101 2 - П,012

1011,11 2 101,1 2 101 2 -1111,001 2

15.Разделите 10010110 2 на 1010 2 и проверьте результат, умножив де­литель на частное.

16.Запишите числа в прямом коде (формат 1 байт):

17. Запишите числа в обратном и дополнительном кодах (формат 1 байт):

18 Найдите десятичные представления чисел, записанных в допол­
нительном коде:

11111000 10011011

11101001 10000000

19. Выполните вычитания чисел путем сложения их обратных (допол­
нительных) кодов в формате 1 байт (укажите, в каких случаях имеет
место переполнение разрядной сетки):

20.Закодируйте с помощью таблицы СР1251 и представьте в шест-надцатеричной системе счисления слово «информация».

21.Почему иногда на экране монитора вместо текстовой информации можно видеть 00DD и т.п.?

22.На клавиатуре наряду с алфавитно-цифровыми клавишами разме­щены такие, как , , и т.д. Имеют ли они десятичный код?

23.При разрешающей способности 1280 х 1024 точек определите объем видеопамяти при глубине цвета High Color.

24.Сколько может «весить», т.е. какой имеет объем, файл с видео­клипом длительностью 5 с?

25.Сколько точек содержит рисунок, если при кодировании каждой точки 1 байт получился файл объемом 300 Кбайт?