a
представляются в виде трех частей:
1. Знак числа s. Под знак числа отводится один ─ первый бит. При этом если число не отрицательное, то s=0, а если отрицательное, то s=1.
2. Следующие 8 бит, отводятся под порядок
P
. На самом деле в этих вось- ми битах хранится смещенный порядок
P
′
,
который получается прибав- лением к порядку
P
смещения равное 126.
3. Под мантиссу
m
отводится 23 бита. Первый бит мантиссы всегда равен
1, поэтому он не хранится в памяти. Таким образом, длину мантиссы получается 24 бита. Следовательно, число типа Single состоит из 33 бит.
Число 0 имеет особый формат. Если все биты равны 0, то число счита- ется равным нулю.
Особым случаем является число, в котором все биты порядка равны 1.
В этом случае, код числа равен либо (-1)
s
∞, если мантисса равна 0, либо код переполнения (
NaN
), если мантисса не равна 0.
s
P
′
m
0 1 8 9 31
138
Алгоритм перевода вещественного числа a, в двоичный формат стан-дарта IEEE 754. 1. Перевести модуль целой части в двоичное число.
2. Переводим дробную часть в двоичный формат.
3. Объединяем полученные целую и дробную части. Для этого к целой части справа приписываем дробную часть. При этом предполагаем, что дробная часть начинается с десятичной запятой.
4. Нормализуем полученное двоичное число. Для этого передвигаем десятичную запятую (влево или вправо) таким образом, чтобы пер- вый бит равный 1 был сразу же справа от десятичной запятой. При этом если запятую передвигали влево, то
порядок будет положи- тельным, а если вправо, то ─ отрицательный. Модуль порядка
P ра- вен величине сдвига десятичной запятой.
5. К порядку
P добавляем число 126, получаем смещенный порядок
P′.
Число
P′
должно быть меньше 255. то
Переводим, полученный смещенный порядок
P′
в двоичный код по алгоритму перевода в двоичный код положительного числа.
6. Записываем в первый бит знак числа
s7. Со второго по 9 бит, записываем двоичный код смещенного порядка
P′.
8. С 10 по 24 бит записываем 23 бита мантиссы, начиная со второго би- та. Т.к. первый бит мантиссы всегда равен 1, то подстановка этого бита осуществляется процессором автоматически.
9. Если число равно нулю, то все 32 бита, заполняем нулями.
10. Если
P′
>254, то все биты заполняются единицами.
Рассмотрим теперь более подробно второй пункт данного алгоритма.
Алгоритм перевода дробной части действительного числа в двоичный формат. 1. В строку, назовем ее R, где будем накапливать результат, ставим десятичную запятую.
2. Умножаем число
a на 2.
a= a.2.
3. Записываем, полученную целую часть справа в строку R.
4. Целую часть полученного числа
a, обнуляем.
5.
Если
a=0, то перейти на пункт 8.
6. Если число разрядов, начиная с первой 1, больше 24, перейти на пункт 8.
7. Перейти на пункт 2.
8. Выводим результат перевода R.
Пример 1. Перевести число A=0,8125 в двоичный формат.
0,8125 =0,1 0,625 =0,11 0,25 =0,110 0,5
=0,1101 2
2 2
2 1,625 1,25 0,5 1,0
Ответ: 0,8125=0,1101 2
139
В данном случае порядок числа P=0. Следовательно, смещенный поря- док P
′=126=7E
16
=01111110 2
В памяти компьютера число 0,8125 хранится в следующем виде:
0
01111110 101 0000 0000 0000 0000 0000.
Для
удобства чтения числа, порядок выделен жирным шрифтом, и ман- тисса разбита на шестнадцатеричные цифры.
Записывать и читать такую длинную последовательности нулей и еди- ниц достаточно трудоемко. Часто это число представляют в шестнадцате- ричном виде также как и целое число. При этом все 32 бита, разбиваем на
8 групп по 4 символа и вместо каждой группы из четырех двоичных цифр записываем одну шестнадцатеричную цифру согласно табл. 11.1.
В шестнадцатеричной системе 0,8125=3FA00000 16
Пример 2. A=0,1.
Такое простое, для десятичной системы счисления, число, в двоичной системе является бесконечной периодической дробью. При умножении его на 2, получаем следующую последовательность: 0,2; 0,4; 0,8; 1,6; 3,2, а дальше последовательность дробной части повторяется.
При ручном переводе дробных чисел, также как и целых, удобнее ис- пользовать шестнадцатеричную систему. В этом случае умножаем дроб- ные числи A на 16, запоминая шестнадцатеричные цифры в целый части, до тех пор, пока дробная часть не превратится в 0, или число шестнадцате- ричных цифр, начиная с первой ненулевой цифры, будет равно 6, если первая значащая цифра от 8 до F (содержит 1 в первом двоичном разряде) или 7, если первая значащая цифра от 1 до 7. Тогда в мантиссе получается не менее 24 значащих разрядов.
0,1 =0,1 0,6
=0,19 0,6 =0,199 0,6 =0,1999 0,6
=0,19999 16 16 16 16 16 1,6 9,6 9,6 9,6 9,6 0,6 =0,199999 0,6
=0,199999916 16 9,6 9,6 0,1=0,1999999 16
=0,0001 1001 1001 1001 1001 1001 1001 2
Нормализуем полученное число, сдвигая запятую вправо на три разря- да.
0,1==0,1100 1100 1100 1100 1100 1100*2
-3 2
Таким образом, P=2. P
′=-3+126=123=7B
16
=
01111011 2
В памяти компьютера число 0,1 хранится в следующем виде:
0
01111011 100 1100 1100 1100 1100 1100.
В шестнадцатеричной системе 0, 1=3DCCCCCC
16
Пример 3. A=-23445,23
Переводим число 23445 в шестнадцатеричный формат. Выкладки про- пускаем. 23445=5B95 16
. Теперь осталось получить три шестнадцатеричных
140
цифр дробной части числа A. 0,23*16=
3
,68. 0,68*16=
10
,88. 0,88*16=
14
,08.
Следовательно, дробная часть числа A=,3AE
16
Таким образом, A=-5B95,3AE
16
В двоичном виде A=-101 1011 1001 0101,0011 1010 1110 2
Нормализуем данное число A=-,1011 0111 0010 1010 0111 0101 2
*2 15
P=-15. P
′=-15+126=111=6F
16
=0110 1111 2
В памяти компьютера число A=-23445,23 хранится в следующем виде:
1
01101111
011 0111 0010 1010 0111 0101.
В шестнадцатеричной системе A=-23445,23 =B7B72A75 16
Приведем некоторые примеры хранения в памяти компьютера еще не- скольких вещественных чисел.
Чис ло
Нормализ ованный вид
Смещен- ный
Порядок
Мантисса Двоичный код
Шестна- дцате- ричный код
0,5 0.1 * 2 0
126=0111 1110 0.1 0 01111110 000 0000 0000 0000 0000 0000 3F000000 0,25 0.1 * 2
-1 125=0111 1101 0.1 001111101 000 0000 0000 0000 0000 0000 3E800000
-5 0.101 * 2 3
129=1000 0001 0.101 110000001 010 0000 0000 0000 0000 0000
C0A00000 127 0.1111111
*2 7
133=1000 0101 0.1111111 010000101 111 1110 0000 0000 0000 0000 42FE0000
Максимальном положительным вещественным числом A
max
, является следующее число:
0 11111110 0111 1111 1111 1111 1111 1111.
Максимальный смещенный порядок равен P
′=254. Следовательно, несмещенный порядок P=254 - 126 = 128. Максимальная мантисса равна:
0,1111 1111 1111 1111 1111 1111 = 1-2
-24
. Т.о., максимальное число равно
A
max
= (1-2
-24
) 2 128
≈3,4*10 38
Минимальным положительным вещественным числом A
min
, является следующее число: 0 00000000 000 0000 0000 0000 0000 0001.
P
′=0. P=0-126=-126. Мантисса m=,1000 0000 0000 0000 0000 0001.
A
min
= (2
-1
+2
-24
)*2
-126
≈ 2
-127
≈ 5,8*10
-39
Напишем теперь функции, реализующие перевод чисел типа Single в двоичный формат, согласно разработанным алгоритмам. Двоичные числа будем хранить в переменных типа String.
Первая функция
ПереводВ2PlusInt
необходима для перевода смещен- ного порядка в двоичный формат. Эта функция переводит любое целое по- ложительное число в двоичный формат. Количество двоичных символов в результирующей строке для числа
ia
равно
ia
2
log
' Перевод Целого положительного числа в двоичный формат
Function ПереводВ2PlusInt(ByVal ia As Long) As String
Dim s As String
141
s = "" ' Здесь накапливаем число в двоичном виде
While ia > 0 'Цикл пока число ia больше 0
' Дописываем слева в строку S остаток от деления числа на 2
s = Trim(str((ia Mod 2))) + s ia = ia \ 2 ' Делим нацело на 2. Остаток от деления
‘отбрасывается
Wend
ПереводВ2PlusInt = s
End Function
Следующая функция ─
ПереводВ2Дробь
переводит в двоичный фор- мат дробную часть десятичного числа типа Single. При этом выходная строка
s
, начинается с символа ”,”, после которой расположен двоичный код дробного числа
d
. При этом строка s содержит 24 двоичные цифры, начиная с первой ненулевой цифры. Это необходимо для получения необ- ходимого числа знаков мантиссы.
' Это функция для перевода дробной части в двоичный код
Function ПереводВ2Дробь(d As Single) As String
Dim s As String, i As Integer, id As Integer i = 0: s = ","
' В переменной S получаем 24 знака (после первой 1) мантиссы
While i < 24 And Len(s) < 100 i = i + 1 ' Количество знаков дробной части после первой 1 id = Int(d * 2) ' Получаем очередную цифру 0 или 1 s = s + Trim(str(id)) 'Дописываем ее в строку s справа
If InStr(s, "1") = 0 Then i = 0 'Пока не появится первая цифра 1, i=0
'Убираем целую часть. Путем вычитания превращаем ее в 0
d = d * 2 - id
Wend
ПереводВ2Дробь = s
End Function
Теперь пишем основную функцию, которая переводит в двоичный формат любое число типа Single.
Function ПереводSingleВДвоичныйФормат(a As Single) As String
Dim s As String, BinIntA As String, ia As Long
Dim d As Single, mant As String, p As Integer, s1 As String
If a < 0 Then s = "1" Else s = "0" 'Знак числа. Первый бит
ia = Int(Abs(a)) ' Целая часть аргумента
d = Abs(a) - ia ' Дробная часть аргумента
'BinIntA -- Двоичный код вещественного числа в виде
' целая часть +","+дробная часть
BinIntA = Trim(ПереводВ2PlusInt(ia)) + Trim(ПереводВ2Дробь(d)) p = InStr(BinIntA, ",") - 1 ' Несмещенный порядок числа
' Если p=0, то порядок или = 0, или отрицательный
If p = 0 Then p = 2 - InStr(BinIntA, "1")
' Получение мантиссы
If p > 0 Then
142
'Берем p разрядов целой части и 24-p бита дробной части mant = Left(BinIntA, p) + Right(BinIntA, Len(BinIntA) - p - 1)
Else
' Порядок <0. Берем 24 бита дробной части, начиная с бита 2-p
mant = Mid(BinIntA, 2 - p, 24)
End If
' Смещенный порядок в двоичном виде
s1 = ПереводВ2PlusInt(p + 126)
' Дополняем слева в порядок нули до 8 символов
s1 = String(8 - Len(s1), "0") + s1 ' Теперь в S1 ровно 8 цифр
' К знаку s добавляем порядок S1 и 23 символа мантиссы mant.
' Со второй по 24. Первый бит мантиссы всегда равен 1, поэтому
' он не храниться
s = s + s1 + Mid(mant, 2, 23)
'Особый случай. Если число равно 0, то по стандарту все
‘биты равны 0
If Abs(a) = 0 Then s = String(32, "0")
ПереводSingleВДвоичныйФормат = s
End Function
Часто приходится решать обратную задачу ─ перевести число из дво- ичного формата в шестнадцатеричный формат. Напишем и такую функ- цию.
Function ПереводИз2ВSingle(s As String) As Single
Dim a As Double, p As Integer, b As Integer, m As Double
Dim i As Integer, d As Double
'Определение смещенного порядка числа 2-9 биты
b = 1: p = 0
For i = 9 To 2 Step -1 'Переводим из 2-ой в десятичную
p = p + Val(Mid(s, i, 1)) * b b = b * 2
Next i p = p - 126 ' Несмещенный порядок
m = 0.5 ' Здесь накапливаем мантиссу
d = 0.5
For i = 10 To 32 ' Цикл по всем разрядам мантиссы
d = d / 2 ' Вес разряда в мантиссе m = m + Val(Mid(s, i, 1)) * d
Next i a = m * 2 ^ p
' Учет знака числа
If Mid(s, 1, 1) = "1" Then a = -a
' Если все биты числа S были =0, то число =0
If p = -126 And m = 0.5 Then a = 0
ПереводИз2ВSingle = a
End Function
143
Для тестирования предложенных функций напишем основную про- грамму. В программе необходимо считать числа типа Single из первого столбца рабочего листа Excel. Перевести в двоичный формат и вывести во второй столбец. Затем, полученное двоичное число перевести в десятич- ный формат и вывести в третий столбец.
Решение: Sub Вариант0Задача24()
Dim i As Integer, a As Single, BinSingleA As String
Sheets("Лист24").Select: i = 0
'
Отформатировать столбец B, в который выводится строка ‘ с результатами перевода в двоичный код, как текстовый Columns("B").NumberFormat = "@"
Do
'Обход по всем элементам последовательности i = i + 1
If Cells(i, 1) = Empty Then Exit Do
'Если ячейка пустая - выйти из цикла a = Cells(i, 1) '
Переписать в переменную а содержимое ячейки ' Переводим действительное число типа Single в двоичный ‘ формат BinSingleA = ПереводSingleВДвоичныйФормат(a)
Cells(i, 2) = BinSingleA
'Записываем его во второй столбец ‘ Производим обратный перевод из двоичного кода в десятичный Cells(i, 3) = ПереводИз2ВSingle(BinSingleA)
Loop
End Sub
В ответе первый и третий столбцы должны совпадать.
11.6. Хранение символьной информации в памяти компьютера Как уже отмечалось выше, все виды информации (числовая, символь- ная, звуковая, видео информация, графическая информация и т.д.) хранят- ся при помощи всего лишь двух символов: 0 и 1. В данном подразделе рас- смотрим методы хранения текстовой информации.
Текстовая информация хранится посимвольно. На каждый символ от- водится по одному байту. Следовательно, в таком формате можно помес- тить не более 256 различных символов. Каждому возможному символу присваивается свой код. Первые 32 символа с кодами от 0 до 31, являются управляющими символами. Для получения кода символа используется функция Asc.
Пример 1. Написать программу, которая выводит в окно вывода код символа, введенного с клавиатуры.
Sub КодыСимволов()
Dim i As Integer, Kod As Integer, c As String * 1, Res As String
For i = 1 To 256
144
c = InputBox("Введите любой символ")
Kod = Asc(c) '
Код введеного символа Res = MsgBox("Символ " + c + " имеет код" + str(Kod) + _
". Продолжать?", vbCritical + vbYesNo + vbDefaultButton1)
If Res = vbNo Then Exit Sub ‘
Выход, если нажали на кнопку No Next i
End Sub
Вторая функция Chr является обратной по отношению к функции Asc.
Функция Chr(Kod) выводит символ соответствующий его числовому коду.
Пример 2. Написать программу, выводящую в ячейки рабочего листа таблицу кодов не управляющих символов.
Sub ТаблицаКодовСимволы()
Dim i As Integer, Kod As Integer, Row As Integer, k As Integer
Sheets("Лист1").Select: Cells.Clear
For i = 32 To 255 ‘
Обходим по всем не управляющим символам k = (i - 32) \ 20 ‘
Выводим по 20 чисел в столбец. K – номер пары Row = ((i - 32) Mod 20) + 1 ‘
Номер строки для вывода Cells(Row, 2 * k + 1) = I '
Код числа Cells(Row, 2 * k + 2) = Chr(i) ‘
Символ Next i
End Sub
Результаты работы программы, представлены в табл. 11.3. Эту таблицу можно использовать при написании программ на текстовые переменные.
Коды цифр расположены подряд в порядке возрастания в интервале от 48 до 57. Латинские буквы расположены так же непрерывным участком по алфавиту в диапазоне от 65 до 90 прописные буквы и от 97 до 122 строч- ные. Русские буквы расположены также непрерывным участком в диапа- зоне от 192 до 255
строго по алфавиту, сначала прописные (192─ 223), а затем строчные (224─255).
Таблица 11.3 32 57 9 82 R 107 k 132 „ 157 ќ 182 ¶ 207 П 232 и
33 ! 58 : 83 S 108 l 133 … 158 ћ 183 · 208 Р 233 й
34 " 59 ; 84 T 109 m 134 † 159 џ 184 ё 209 С 234 к
35 # 60 < 85 U 110 n 135 ‡ 160 185 № 210 Т 235 л
36 $ 61 = 86 V 111 o 136 € 161 Ў 186 є 211 У 236 м
37 % 62 > 87 W 112 p 137 ‰ 162 ў 187 » 212 Ф 237 н
38 & 63 ? 88 X 113 q 138 Љ 163 Ј 188 ј 213 Х 238 о
39
' 64 @ 89 Y 114 r 139 ‹ 164 ¤ 189 Ѕ 214 Ц 239 п
40 ( 65 A 90 Z 115 s 140 Њ 165 Ґ 190 ѕ 215 Ч 240 р
41 ) 66 B 91 [ 116 t 141 Ќ 166 ¦ 191 ї 216 Ш 241 с
42 * 67 C 92 \ 117 u 142 Ћ 167 § 192 А 217 Щ 242 т
43 + 68 D 93 ] 118 v 143 Џ 168 Ё 193 Б 218 Ъ 243 у
44 , 69 E 94 ^ 119 w 144 ђ 169 © 194 В 219 Ы 244 ф
45 - 70 F 95 _ 120 x 145 ‘ 170 Є 195 Г 220 Ь 245 х
145 46 . 71 G 96 ` 121 y 146 ’ 171 « 196 Д 221 Э 246 ц
47 / 72 H 97 a 122 z 147 “ 172 ¬ 197 Е 222 Ю 247 ч
48 0 73 I 98 b 123 { 148 ” 173 - 198 Ж 223 Я 248 ш
49 1 74 J 99 c 124 | 149 • 174 ® 199 З 224 а 249 щ
50 2 75 K 100 d 125 } 150 – 175 Ї 200 И 225 б 250 ъ
51 3 76 L 101 e 126 151 — 176 ° 201 Й 226 в 251 ы
52 4 77 M 102 f 127 152 177 ± 202 К 227 г 252 ь
53 5 78 N 103 g 128 Ђ 153 ™ 178 І 203 Л 228 д 253 э
54 6 79 O 104 h 129 Ѓ 154 љ 179 і 204 М 229 е 254 ю
55 7 80 P 105 i 130 ‚ 155 › 180 ґ 205 Н 230 ж 255 я
56 8 81 Q 106 j 131 ѓ 156 њ 181 µ 206 О 231 з
Пример 3. Написать программу, переводящую в двоичный код строку, введенную с клавиатуры.
Sub ПереводВДвоичныйКодСтроки()
Dim s As String, bin As String, i As Long, kod As Byte, k As Byte
Dim c As String s = InputBox("Введите строку") bin = "" '
Здесь будем накапливать двоичный код строки For i = 1 To Len(s)
'Цикл по всем символам введенной строки kod = Asc(Mid(s, i, 1)) '
Код i-того символа c = ""
' Здесь получаем двоичный код символа For k = 1 To 8
'Получить 8 двоичных цифр кода i-того символа c = Trim(str((kod Mod 2))) + c
'Слева дописать двоичную цифру kod = kod \ 2
' Уменьшить в два раза число Next k
'
В строку bin, cправа дописать код полученного символа bin = bin + c + " "
Next i
'
Вывести в окно отладки двоичный код, введенного текста Debug.Print bin
End Sub