Системы представления чисел

Тема в разделе "WASM.ARTICLES", создана пользователем Mikl___, 31 янв 2017.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709

    Системы представления чисел


    Если вы всерьез собрались научиться разрабатывать микропроцессорные устройства, тогда вам необходимо знать, как компьютер хранит и обрабатывает числа. К сожалению люди не придумали способа записывать при помощи электронных сигналов числа в том виде как мы их привыкли видеть (вернее пытались, но попытки закончились неудачно), поэтому матемaтикам и инженерам пришлось придумать другой, более подходящий способ.
    Система счисления ― это совокупность приемов представления обозначения натуральных чисел. В обычной жизни используются два способа представления чисел ― при помощи индийских и римских цифр. Одно и тоже число можно записать как 2 или как II, как 5 или как V, как 22 или как XXII. Перед нами два альтернативных способа написания чисел. Числа одинаковые, а способы написания разные.
    [​IMG][​IMG]
    Если есть два способа, почему бы не придумать третий, четвертый и далее? Были придуманы несколько способов представления чисел. Один из этих способов (двоичный способ представления чисел) подходит для реализации его при помощи электроники.
    Другие (восьмеричный и шестнадцатеричный) способы помогают удобнее представлять компьютерные данные на бумаге или на экране.
    За основу универсального приема, позволяющего создавать различные способы представления чисел были взяты индийские цифры и позиционный способ представления числа. Согласно этому принципу один и тот же цифровой знак имеет различные значения в зависимости от того места (позиции), где он расположен. Такая система счисления основывается на том, что некоторое число из n единиц (основание системы счисления) объединяется в единицу второго разряда, n единиц второго разряда объединяются в единицу третьего разряда и так далее.
    «Разрядам» учат в начальных классах школы. Например, у числа 35672 цифра «2» соответствует первому разряду, «7» ― второму, «6» ― третьему, «5» ― четвертому и «3» ― пятому. А «различные значения» цифрового знака «в зависимости от того места, где он расположен» и «объединение в единицу старшего разряда» очень наглядно отображают обыкновенные бухгалтерские счеты.
    Чтобы набрать число 35672 мы должны передвинуть влево две «костяшки» на первом «прутике», 7 на втором, 6 на третьем, 5 на четвертом и 3 на пятом. (1 «костяшка» на втором «прутике» ― это то же самое, что и 10 «костяшек» ― на первом, а одна на третьем равна десяти на втором ― и так далее...) Пронумеруем наши «прутики» снизу вверх ― так, чтобы номер первого «прутика» был равен нулю.
    35672 = 3⋅104 + 5⋅103+ 6⋅102 + 7⋅101 +2⋅100сколько на каждом «прутике» сдвинутых влево «костяшек»;
    35672 = 3⋅104 + 5⋅103+ 6⋅102 + 7⋅101+ 2⋅100номер «прутика»;
    35672 = 3⋅104 + 5⋅103+ 6⋅102 + 7⋅101 +2⋅100число «костяшек» на каждом «прутике».
    Оттолкнувшись от записи конкретного числа 35672 можно записать любое пятизначное число как
    a4a3a2a1a0=a4×104+a3×103+a2×102+a1×10+a0
    где a4, a3, a2, a1 и a0 ― какие-то десятичные цифры, а число 10 ― основание системы представления. Компактный способ написания разложения (n+1)-значного числа в линейную комбинацию степеней базы выглядит вот так:
    anan-1...a2a1a0=[math]\displaystyle \sum^{n+1}_{k=0}[/math]ak×10k
    В большинстве стран мира считают одинаково, используя десять цифр (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Когда доходят до последней цифры, используют двухзначные числа. Когда заканчиваются двухзначные числа ― начинают использовать трехзначные и так далее... Число десять выбрано потому, что у нас на двух руках десять пальцев

    [​IMG][​IMG][​IMG]
    Если бы у человека было на каждой руке только по четыре пальца, как у героев диснеевских мультфильмов (рис. #1), тогда бы ему никогда не пришла в голову мысль о системе счисления, основанной на десяти. Вместо нее нормальной и единственно разумной системой счисления считалась бы система, основанная на восьми пальцах. И называлась бы такая система не десятичной (decimal), а восьмеричной (octal). В восьмеричной системе счисления не нужен символ 9. В десятичной системе нет специального символа для десяти, поэтому в восьмеричной системе нет специального символа для 8.
    В десятичной системе начало натурального ряда чисел выглядит так: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... В восьмеричной системе уже так: 0, 1, 2, 3, 4, 5, 6, 7 и... что дальше? Символы-то закончились. Выход один ― после 7 поставить 10. Но эта десятка уже не равна числу пальцев на двух руках человека. В восьмеричной системе 10 ― это количество пальцев на двух руках мультяшки.
    Даже когда пальцы на ногах и руках будут исчерпаны, счет в восьмеричной системе можно продолжать. В целом он идет, как и счет в десятичной системе, но без чисел, содержащих цифры 8 и 9:
    0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 21, 22, 23, 24, 25, 26, 27, 30, 31, 31, 32, 33, 34, 35, 36, 37, 40, 41, 41, 42, 43, 44, 45, 46, 47, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 67, 70, 71, 72, 73, 74, 75, 76, 77, 100...

    [​IMG]
    «Дети шпионов». 2001. Пал Палычи​
    А теперь представьте себе как считают вот такие существа (рис. #2). На обоих руках у них всего два пальца, поэтому обходятся они всего двумя цифрами: 0 и 1. Система счисления, основанная на двух цифрах, называется двоичной (binary).
    В двоичной системе сразу после 1 идет 10. В любой системе счисления, когда заканчиваются одноразрядные числа, первое двухразрядное число ― 10. Начало натурального ряда чисел в двоичной системе:
    0, 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, 10000, 10001...
    Закрепим. Если бы у нас было только пять цифр, 0, 1, 2, 3, 4, тогда начало натурального ряда чисел выглядело бы так:
    0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44, 100, 101, 102, 103, 104, 110, 111, 112...
    «Обычную» систему представления чисел называют «десятичной». Систему представления чисел, которую мы только что рассмотрели ― пятеричной. Число цифр в системе представления чисел (количество пальцев на двух руках) называют «основанием системы представления чисел» или базой.
    Если основании системы более десяти, тогда приходится вводить новые «цифры». В качестве «новых цифр» принято использовать латинские буквы. Так, в семнадцатеричной системе представления начало натурального ряда чисел выглядит вот так:
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 1G, 20, ..., GD, GE, GF, GG, 100, 101, 102, ...
    Задание #1: При каком достаточно большом основании способ с использованием латинских букв не подойдет?
    Разные системы представления чисел ― как разные языки. У одного и того же числа могут быть совершенно разные записи в разных системах представления. Так, десятичному представлению числа 2785 соответствует шестнадцатеричное представление AE1, восмеричное 5341 и двоичное 101011100001. Точно так же, как слова переводят с одного языка на другой, числа можно переводить из одной системы представления в другую. Двоичная система представления чисел используется в компьютерах. К недостатку двоичной системы представления можно отнести «длинную» запись числа (чем меньше в системе представления цифр, тем длиннее будет представление числа) ― четырем цифрам в десятичном представлении числа 2785 соответствует двенадцать цифр в двоичном представлении 101011100001
    Шестнадцатеричная (hexadecimal) и восьмеричная системы представления чисел позволяют вместо длинных цепочек из нулей и единиц записывать более «короткие» числа, что облегчает написание и корректировку программ. Шестнадцатеричная и восьмеричная системы ― промежуточное звено между машиной и человеком, между двоичной и десятичной системами представления чисел.
    Разумеется, что нули перед числом не изменяют его значение ни в одной из систем представления.

    Задание #2: Посчитайте немного в различных системах представления. Возьмите листочек «в клеточку» и пронумеруете строчки сначала в десятичной системе представления, потом в восьмеричной, шестнадцатеричной и двоичной ― получите табличку перевода первых тридцати чисел в наиболее часто используемых системах представления. Напишите на этой таблице также числовые значения всех латинских букв ― это пригодится в дальнейшем.
     

    Вложения:

    • d0.jpg
      d0.jpg
      Размер файла:
      6,5 КБ
      Просмотров:
      4.061
    • d1.jpg
      d1.jpg
      Размер файла:
      82 КБ
      Просмотров:
      4.224
    • d2.jpg
      d2.jpg
      Размер файла:
      21,7 КБ
      Просмотров:
      4.072
    • d3.jpg
      d3.jpg
      Размер файла:
      97,5 КБ
      Просмотров:
      4.100
    • d4.jpg
      d4.jpg
      Размер файла:
      9,7 КБ
      Просмотров:
      991
    • latex.cgi.gif
      latex.cgi.gif
      Размер файла:
      909 байт
      Просмотров:
      1.171
    DrochNaNoch и rasstriga нравится это.
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Для представления бинарных файлов в текстах писем в электронной почте используется 6-ричное кодирование base64, которое при помощи 64(=26) символов (текстово-цифровые латинские символы A-Z, a-z и 0-9 (62 знака) и 2 дополнительных символа, зависящих от системы реализации)
    Или вообще попробуйте считать в 256-ричной (=28) системе счисления, используя в качестве «цифр» таблицу ASCII-символов
    Компьютер, как известно, считает только в двоичной системе счисления. Человеку привычна десятичная. Так для чего еще и шестнадцатеричную какую-то знать нужно?
    Все очень просто. В умных книжках пишут, что «шестнадцатеричная нотация является удобной формой представления двоичных чисел». Что это значит?
    Переведите число A23F из шестнадцатеричной «нотации» в двоичную. (Один из возможных алгоритм приведен в #3). В результате длительных манипуляций у вас должно получиться 1010001000111111.
    А теперь еще раз посмотрите на таблицу #2. (которую вы как бы уже и выучили) и попробуйте то же самое сделать «в уме»:
    A23F [math]\underbrace{1010}_{A}\;\underbrace{0010}_{2}\;\underbrace{0111}_{3}\;\underbrace{1111}_{F}[/math] 1010 0010 0011 1111
    Каждой шестнадцатеричной цифре соответствует тетрада (4 штуки) ноликов и единичек. Все, что потом нужно сделать ― «состыковать» эти тетрады. Круто? Вас еще не то ждет!
    Конкретный рисунок цифр не важен. То, что ноль обозначается кружочком, а единица ― палочкой, всего лишь «историческая условность».
    [​IMG]
    Лаосские, кхмерские, тайские цифры​
    [​IMG]
    Тайланд, 20 бат​
    [​IMG]
    бирманские цифры​
    [​IMG]
    Бирма, 50 кьят​
    Можно «нормально считать» в троичной системе представления чисел с цифрами «%», «!», «^» и тогда начало натурального ряда чисел будет выглядеть вот так:
    %, !, ^, !%, !!, !^, ^%, ^!, ^^, !%%, !%!, !%^, !!%, !!!, !!^, !^%, !^!, !^^, ^%%...
    Точно также не стоит воспринимать всерьез требования использовать латинские буквы после девятки. ASCII-символы, стоящие после девятки («:;<=>?@») ничем не хуже:).
    Для указания системы представления надо указывать не ее основание, а вектор (упорядоченный массив) ее «цифр». Считая в системах представления с вектором основания, в котором цифры идут «не по порядку» (например, восьмеричная система с вектором «31276504»), можно существенно затруднить понимание происходящего.
    Существует система представления состоящая из двадцати шести латинских букв, с вектором основания «A B C D E F G H I J K L M N O P Q R S T U V W X Y Z» ― со всеми латинскими буквами в алфавитом порядке. В такой системе представления, к примеру, десятичное число 10 будет записываться как «K». Число «DOG», переведенное из этой системы в десятичную, будет равно 2398. (Проверьте.)
    Задание #3: Самостоятельно попереводите разные числа из 26-ричной системы в двоичную и десятичную и обратно.
    Принято указывать основание системы представления внизу-справа от числа. При этом основание записывается в десятичной системе представления. Например ― 1FC16 обозначает число 1FC в шестнадцатеричной системе представления.
    Задание #4: Заметьте (или проверьте по своей таблице), что [math] 1\overbrace{000\cdots 00_x}^{n} =x^n[/math]
    где N ― количество нулей после единицы, а x основание системы счисления.
    Алгоритм перевода числа из любой системы в десятичную систему

    Если перейти от десятичной записи числа к записи числа в p-ричной системе представления, то изменений будет не очень много
    [math]a_{n}a_{n-1}\cdots a_{1}a_{0}=a_{n}\cdot p^{n}+a_{n-1}\cdot p^{n-1}+\cdots +a_{1}\cdot p+a_{0}=\displaystyle \sum^{n+1}_{k=0} a_{k}\cdot p^k[/math]

    где ak[math]\{0, 1, 2,\cdots , p-1\}[/math] и an 0 То есть число равно сумме его цифр, умноженных на основание p возведенное в соответствующую степень k. В качестве примеров используем переводы числа «1210» из троичной системы и числа «C00L» из двадцатидвухричной системы в десятичное представление:
    12103 = 1⋅33 + 2⋅32 + 1⋅3 + 0 = 27 + 18 + 3 = 4810
    C00L22 = 12⋅223 + 0⋅222 + 0⋅22 + 21 = 127776 + 21 = 12779710
    Задание #5: Попробуйте попереводить побольше чисел из самых различных систем представления (желательно без использования калькулятора), выполняя все арифметические действия в уме или на листочке.
    Применив «схему Горнера», получим более эффективную версию алгоритма
    12103 = ((1⋅3+2)⋅3+1)⋅3+0 = 16⋅3 = 48
    C00L22 = (((12⋅22+0)⋅22+0)⋅22+21 = 127776 + 21 = 127797
    Эффективность алгоритма в том, что не требуется возведение в степень ― перевод получается значительно быстрее и короче.
    Задание #6: Переводите числа из любой системы представления в привычный нам десятичный вид.
    Вам нужно постоянно быть в боевой готовности ― кто знает, где придется демонстрировать своё искусство :).
    Если под рукой есть только примитивный калькулятор с четырьмя арифметическими действиями (например, калькулятор в телефоне), то по традиционному методу вам придется где-то записывать, а потом набирать промежуточные результаты. По новому методу вам потребуется лишь набирать между цифрами знак умножения, основание системы представления чисел и знак сложения.
    Если под рукой не оказалось даже примитивного калькулятора, тогда новый алгоритм можно использовать для перевода числа столбиком.
    [​IMG]
    Алгоритм перевода числа из десятичной системы в любую систему

    Мы переводили числа из «странной записи» в «обычную». При вводе десятичных чисел в компьютер требуется обратное действие ― десятичные числа должны быть переведены в «машинный вид». Хотя эта операция обычно выполняется компьютером, для лучшего понимания мы проделаем эту операцию самостоятельно.
    Обратное действие (перевод из десятичной системы представления в произвольную) обычно выполняется, когда мы хотим ввести информацию в компьютер. Мы живем в «десятичном мире», а компьютер ― в двоичном. Для того, чтобы ввести что-нибудь в «мир компьютера», нам придется переводить числа в «чужую» систему представления.
    Тут надо уметь делить. Переведем числа обратно в «родную систему представления», последовательно делим число на основание, пока не получится число, меньше чем основание.
    [​IMG]
    Результат собирается из последнего частного и остатков в обратном порядке. В первом случае получаем 12103, а во втором ― C00L22.
    Задание #7: Попробуйте несколько десятичных чисел перевести во всякие «странные системы представления», а затем переведите получившиеся числа обратно в десятичную систему представления.
    Если вы хорошо делите «в уме» (или используете калькулятор), тогда удобнее использовать другую запись:
    [​IMG]
    при каждом делении остаток записывается справа от черты, а частное ― внизу. Ответ считывается в обратном порядке ― снизу вверх.
    Задание #8: Напишите программу, выполняющую автоматический перевод в любую систему представления чисел.
    Таблица #1. Цифры разных систем представления чисел

    Система счисленияОснованиеИспользуемые цифры
    двоичная20,1
    четверичная40, 1, 2, 3
    восьмеричная80, 1, 2, 3, 4, 5, 6, 7
    десятичная100, 1, 2, 3, 4, 5, 6, 7, 8, 9
    шестнадцатеричная160, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

    Таблица #2. Эквиваленты записи чисел в разных системах представления
    Двоич-
    ная
    Чет-
    ве-
    рич-
    ная
    Вось-
    ме-
    рич-
    ная
    Деся-
    тич-
    ная
    Шест-
    над-
    цате-
    рич-
    ная
    Двоично-десятичные
    (BCD ― binary-coded decimal)
    8.4.2.1Tele-
    commu-
    nication
    01236
    7.4.2.18.4.-2.-15.4.2.12.4.2.1
    0​
    0​
    0​
    0​
    0​
    0000 000001100 011001100 11000000 00000000 00000000 0000
    1​
    1​
    1​
    1​
    1​
    0000 000101100 110001100 00010000 01110000 00010000 0001
    10​
    2​
    2​
    2​
    2​
    0000 001001100 101001100 00100000 01100000 00100000 0010
    11​
    3​
    3​
    3​
    3​
    0000 001101100 100101100 00110000 01010000 00110000 0011
    100​
    10​
    4​
    4​
    4​
    0000 010001100 010101100 01000000 01000000 01000000 0100
    101​
    11​
    5​
    5​
    5​
    0000 010101100 001101100 01010000 10110000 10000000 1011
    110​
    12​
    6​
    6​
    6​
    0000 011001100 100011100 01100000 10100000 10010000 1100
    111​
    13​
    7​
    7​
    7​
    0000 011101100 010011100 10000000 10010000 10100000 1101
    1000​
    20​
    10​
    8​
    8​
    0000 100001100 001011100 10010000 10000000 10110000 1110
    1001​
    21​
    11​
    9​
    9​
    0000 100101100 000111100 10100000 11110000 11000000 1111
    1010​
    22​
    12​
    10​
    А​
    0001 000011000 011000001 11000111 00000001 00000001 0000
    1011​
    23​
    13​
    11​
    B​
    0001 000111000 110000001 00010111 01110001 00010001 0001
    1100​
    30​
    14​
    12​
    C​
    0001 001011000 101000001 00100111 01100001 00100001 0010
    1101​
    31​
    15​
    13​
    D​
    0001 001111000 100100001 00110111 01010001 00110001 0011
    1110​
    32​
    16​
    14​
    Е​
    0001 010011000 010100001 01000111 01000001 01000001 0100
    1111​
    33​
    17​
    15​
    F​
    0001 010111000 001100001 01010111 10110001 10000001 1011
    10000​
    100​
    20​
    16​
    10​
    0001 011011000 100010001 01100111 10100001 10010001 1100
     

    Вложения:

    • hobbit31.png
      hobbit31.png
      Размер файла:
      79 КБ
      Просмотров:
      4.383
    • latex.cgi2.gif
      latex.cgi2.gif
      Размер файла:
      638 байт
      Просмотров:
      1.053
    • screen-capture-51.jpg
      screen-capture-51.jpg
      Размер файла:
      20,4 КБ
      Просмотров:
      4.196
    • 51.jpg
      51.jpg
      Размер файла:
      17,4 КБ
      Просмотров:
      4.179
    • 00.jpg
      00.jpg
      Размер файла:
      11,7 КБ
      Просмотров:
      4.008
    • 52.jpg
      52.jpg
      Размер файла:
      35,1 КБ
      Просмотров:
      4.057
    • latex3.gif
      latex3.gif
      Размер файла:
      1,4 КБ
      Просмотров:
      1.212
    • 49.png
      49.png
      Размер файла:
      7,9 КБ
      Просмотров:
      4.160
    • 48.png
      48.png
      Размер файла:
      3,3 КБ
      Просмотров:
      4.096
    • 50.png
      50.png
      Размер файла:
      11,1 КБ
      Просмотров:
      4.618
    rasstriga, Alexey, galenkane и ещё 1-му нравится это.
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Теперь от теории перейдем к практике. Вам понадобится переводить из/в шестнадцатеричную, десятичную, восьмеричную, двоичную системы.
    Итак, разберем все случаи. Будьте внимательны ― здесь есть подводные камни!
    16→2
    Это просто ― так как 24=16 поэтому каждой шестнадцатеричной цифре ставятся в соответствие четыре бита («ниббл», «тетрада» или «полубайт») по таблице #2. После перевода всего числа, нолики слева («лидирующие нули»), если они есть, разумеется, можно удалить.
    [math]12FC_{16}\to\underbrace{{\color{red}{000}}1}_{1}\;\underbrace{0010}_{2}\;\underbrace{1111}_{F}\;\underbrace{1100}_{C}\to 1001011111100_2[/math]
    2→16
    Не на много сложнее ― двоичные разряды объединяются в «четверки» СПРАВА, при этом последняя «четверка» может оказаться «тройкой», «двойкой» или даже одной цифрой, тогда в качестве недостающих разрядов слева дописываются нули. Затем из таблицы #2 вместо «четверок» выписываются соответствующие шестнадцатеричные цифры.
    [math]1011001011_2\to\underbrace{{\color{red}{00}}10}_{2}\;\underbrace{1100}_{C}\;\underbrace{1011}_{B}\to 2CB_{16}[/math]
    8↔2
    Переводы из шестнадцатеричной в двоичную систему и из восьмеричной в двоичную очень похожи, только используется разбивка двоичного числа на тройки («триады») битов (23=8).
    [math]276_8\to \underbrace{{\color{red}{0}}10}_{2}\;\underbrace{111}_{7}\;\underbrace{110}_{6}\to 10111110_2[/math]
    [math]1011001011_2\to \underbrace{{\color{red}{00}}1}_{1}\;\underbrace{011}_{3}\;\underbrace{001}_{1}\;\underbrace{011}_{3}\to 1313_8[/math]
    ВНИМАНИЕ! Алгоритмы существуют лишь для переводов 16↔2 и 8↔2. Для перевода 16↔8 надо использовать промежуточную двоичную систему представления чисел. Использование же алгоритмов для перевода в десятичную систему или из нее ― грубейшая ошибка!
    Вообще, запомните формулу 8↔2↔16.

    ВНИМАНИЕ! Распространенное заблуждение!
    У каждого программиста в жизни бывает период, когда он вдруг (по какой-то необъяснимой причине) начинает считать, что числа, в которых не используются буквы, не меняются при переводе в десятичную систему. То есть, например, 12316=12310. Так вот, ЭТО НЕ ТАК! Подумайте, почему.
    Задание #9: Посчитайте, чему равно 12316
    2→10
    Часто требуется переводить байты и слова из двоичной системы в десятичную.
    1. Лобовое решение, но не самое лучшее
      [math]101011010101001010001=2^{20}+2^{18}+2^{16}+2^{15}+2^{13}+2^{11}+2^9+2^6+2^4+1=[/math]
      [math]=1048576+262144+65536+32768+8192+2048+512+64+16+1=1419857[/math]
    2. Можно использовать калькулятор «Пуск» [math]\to[/math] «Все программы» [math]\to[/math] «Стандартные» [math]\to[/math] «Калькулятор» и «Вид» [math]\to[/math] «Программист»
    [​IMG]
    2→16→10
    Вместо того, чтобы долго и нудно вычислять степени двойки, а потом подсчитывать их сумму, можно быстро перевести число в шестнадцатеричную систему представления чисел, а уже потом из нее ― в десятичную. Экономится куча времени.
    [math]\underbrace{1010}_{A}\;\underbrace{1001}_{9} = 10\cdot 16+9 = 169[/math]
    Байт переводится мгновенно и в уме! Запомните несколько степеней 16: 162=256, 163=4096 164=65536 и 165=1048576 ― пригодится!

    Алгоритм Содена

    быстрый алгоритм перевода из двоичной системы в десятичную предложен Уолтером Соденом (Walter Soden) в 1953 году.
    1. Сначала переведем число из двоичной системы в восьмеричную. Например,1010110101010010100012→101.011.010.101.001.010.0012→53251218
    2. Далее выполним перевод из восьмеричной системы в десятичную. Разница между системами представления 10 - 8 = 2. Нужно у восьмеричного представления числа удваивать на k-м шаге k ведущих разряда используя десятичную арифметику, и вычесть полученный результат из (k+1) ведущих разрядов при помощи десятичной арифметики. Если заданное число содержит (m+1) восьмеричных цифр, тогда преобразование займет m шагов. Для выделения удваиваемых разрядов используем «разделяющую точку». Это поможет исключить возможные ошибки
      [​IMG]
    3. 1010110101010010100012→53251218→141985710
    Если двоичное число не очень длинное. тогда можно перевести непосредственно из двоичного представления в десятичное, не прибегая к промежуточному восьмеричному представлению. Разница между системами представления 10 - 2 = 8.
    [​IMG]
    11111100012→100910

    10→2


    1. Алгоритм перевода из десятичной системы в двоичную, предложенный Шарлем Розье (Charles P. Rozier) в 1962 году, почти такой же.
      1. Сначала переводим число в промежуточную восьмеричную запись. Для этого, заданное в десятичном формате число, удвоим на k-м шаге k ведущих разрядов, используя представление в восьмеричном формате, и сложим полученные(k+1) ведущих разрядов при помощи восьмеричной арифметики. Для заданного числа, содержащего (m+1) цифр преобразование закончится через m шагов. Например,
        [​IMG]
      2. Далее переводим восьмеричное число в двоичное. [math]5325121_8\to 101.011.010.101.001.010.001_2\to 101011010101001010001_2[/math]
      3. [math]1419857_{10}\to 5325121_8\to 101011010101001010001_2[/math]
    2. получаем двоичный вид числа от последней двоичной цифры к первой. Число последовательно делится на 2 до получения частного равного нулю. Представление числа в двоичной системе – это упорядоченная последовательность остатков от деления в порядке, обратном их получению (старшую цифру числа дает последний остаток, а младшую – первый). Начинаем с n=0
      1. Делим число на 2. Запомним частное qn и остаток an.
      2. Если в результате деления частное qn ≠ 0, тогда принимаем qn за новое делимое, увеличиваем n на 1 и возвращаемся к пункту 1.
      3. Если в результате деления частное qn = 0, тогда выписываем остатки в обратном порядке anan-1a1a0. Это и будет число представленное в двоичной системе счисления.
      Получение двоичного вида числа 147:
      [​IMG]
    3. вычисляем двоичный вид числа начиная с первой двоичной цифры. Для этого придется запомнить степени 2 (210=1024, 29=512, 28=256, 27=128, 26=64, 25=32, 24=16, 23=8, 22=4). Для примера рассчитаем как будет выглядеть двоичное представление того же числа 147, ищем ближайшую степень двойки 27=128 <147< 28=256 Определившись со степенью n – делим десятичное представление числа на 2n. Результатом будет первая двоичная цифра и остаток. Остаток делится на 2n-1 и так далее, пока остаток не станет меньше 2, а степень нулевой.
      [​IMG]
    4. похоже на третий вариант, но деление заменено на вычитание. Преобразуем десятичное число 84 в двоичное. Определяем, ЧТО должно стоять в каждом разряде двоичного числа: 1 или 0. Находим наибольшую степень 2, меньше или равную заданному числу 26=64 < 84 < 128=27, и ставим 1 в 6-ой разряд. Далее 84–64 = 20, 20 < 32=25, поэтому в 5-ый разряд ставим 0, 20 > 16=24, в 4-ый разряд ставим 1. Остается 20 –16 = 4. 4 < 8=23, ставим 0 в третий разряд. 4=22, – ставим 1 во второй разряд и нули в разряды 1 и 0. Собрав все вместе, получаем 84 = 10101002
    10→16

    1. сперва находим последнюю цифру, затем предпоследнюю и так далее... Число в десятичной форме записи 42936 переводится следующим образом:
      [​IMG]
    2. Второй вариант перевода числа из десятичного вида в шестнадцатеричный – сперва находим первую цифру, затем вторую и так далее... Для начала придется запомнить степени 16 (165=1048576, 164=65536, 163=4096, 162=256).
      Начинаем с вычисления старшего разряда и определения его порядка в шестнадцатеричном виде числе, если десятичное число между 1 и 16 миллионами – начинаем с деления на 1048576, если между миллионом и 65 тысячами – начнем с деления на 65536 и так далее. Определившись со степенью – делим десятичное представление числа на 16n. Результатом будет первая шестнадцатеричная цифра и остаток. Остаток делится на 16n-1 и так далее, пока остаток не станет меньше 16, а степень нулевой. Для примера рассчитаем шестнадцатеричное представление числа:
      [​IMG]
    3. Преобразуем число 333 в шестнадцатеричное. Найдем наибольшую степень шестнадцати, меньшую или равную заданному числу. [math]log_{16}(333)=2,094844592[/math] [math]16^2 = 256 < 333 < 4096 = 16^3[/math]
     

    Вложения:

    • 47.png
      47.png
      Размер файла:
      14,4 КБ
      Просмотров:
      5.118
    • 46.png
      46.png
      Размер файла:
      10,1 КБ
      Просмотров:
      4.252
    • 329009d1384422243.jpg
      329009d1384422243.jpg
      Размер файла:
      23,8 КБ
      Просмотров:
      4.129
    • 330546d1384854133.gif
      330546d1384854133.gif
      Размер файла:
      3,7 КБ
      Просмотров:
      4.245
    • 45.png
      45.png
      Размер файла:
      9,6 КБ
      Просмотров:
      4.224
    • 329010d1384421144.jpg
      329010d1384421144.jpg
      Размер файла:
      17,9 КБ
      Просмотров:
      4.147
    • 330547d1384854145.gif
      330547d1384854145.gif
      Размер файла:
      3,4 КБ
      Просмотров:
      4.090
    • 50.png
      50.png
      Размер файла:
      30,6 КБ
      Просмотров:
      4.207
    • d10.png
      d10.png
      Размер файла:
      19,2 КБ
      Просмотров:
      4.055
    • d11.png
      d11.png
      Размер файла:
      19,4 КБ
      Просмотров:
      4.081
    rasstriga, galenkane и rococo795 нравится это.
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Число [math]256[/math] содержится в числе [math]333[/math] только один раз, поэтому во второй разряд записываем единицу. [math]333–256=77[/math]. Число [math]16[/math] содержится в числе [math]77[/math] четыре раза, поэтому в первый разряд записываем четверку. Остается [math]77 – 16\times 4 = 13 = D_{16}[/math], поэтому в нулевой разряд записываем [math]D[/math]. [math]333_{10} = 14D_{16}[/math]
    16→10
    Обратный процесс – переведем число из шестнадцатеричного вида в десятичный – возьмем число A7B8 и учтем, что каждая шестнадцатеричная цифра всегда в 16 раз больше ближайшей цифры справа: ((A⋅16+7)⋅16+B)⋅16+8=(167⋅16+11)⋅16+8=2683⋅16+8=42936
    [​IMG]

    Задание #10: Переведите из десятичной системы в двоичную систему число 12345678987654321.
    Задание #11: Переведите из двоичной системы в десятичную систему число 10101010101010101

    Обозначения

    На самом деле, такую глобальную роль шестнадцатеричная и восьмеричная системы представления чисел играют исключительно благодаря тому, что 8=23, а 16=24. Внутри машина считает исключительно «по-двоичному». Шестнадцатеричная и восьмеричная системы представления чисел позволяют вместо длинных цепочек из нолей и единиц записывать более короткие строки из чисел. Эти системы ― промежуточное звено между машиной и человеком, между двоичной и десятичной системами представления чисел.
    Роль систем представления чисел огромна! К примеру, права доступа к файлу в системе UNIX изменяются из shell'а командой chmod. Эта команда требует задания аргумента (прав доступа) в восьмеричной системе представления чисел! Команда
    chmod 666 /etc/passwd
    открывает доступ на чтение и запись всем пользователям к файлу паролей в системе UNIX. Даже системные администраторы должны разбираться в восьмеричной системе представления чисел. Так чего же говорить о программистах, пишущих на языке ассемблер!
    В различных языках программирования числа в этих системах обозначаются по разному.
    Таблица #3. Сводная таблица для основных языков:
    C/C++PascalBASICAssembler
    DEC12121212 ,12d, 12t
    HEX0xC$C&hC0Ch, 3F800000r
    OCT014&o1414o, 14q
    BIN&b11001100b, 1100y
    Нули в начале числа не влияют на его значение. Создатели языка Cи решили по другому. Поскольку никто в здравом уме не начинает числа с нуля (кому охота набивать лишние символы?), ноль в начале числа используется для обозначения признака восьмеричного числа.
    При всех способах записи регистр букв неважен. Даже строгий на регистры Cи позволяет начинать шестнадцатеричные числа как с 0x, так и с 0X. Кстати, в ранних версиях компиляторов Cи различных фирм шестнадцатеричные числа надо было начинать с 0x0.
    При программировании на ассемблере если шестнадцатеричное число начинается с буквы, перед ним обязательно должен ставится ноль. Иначе ассемблер подумает, что вы имели в виду переменную Ch, а не число C16. Но некоторые не способны запомнить это правило, ставят ноль впереди всех шестнадцатеричных чисел.
    В диалект MASM дополнительно к суффиксам D, O, H и B добавлены суффиксы T, Q, R и Y. Дело в том, что с помощью директивы .RADIX ассемблер позволяет менять систему представления чисел, действующую по умолчанию. Раньше, когда систему представления чисел изменяли на шестнадцатеричную, числа вроде 12D, которые с первого взгляда являются обычными шестнадцатеричными, интерпретировались как 1210. Это порождало сеть мелких и незаметных ошибок, мешавших использовать .RADIX 16.
    Мы будем использовать все способы записи чисел, используя ассемблерный способ как основной. Вы должны хорошо владеть всеми способами.

    Арифметика

    В любой их систем представления чисел можно по прежнему складывать, вычитать, делить и умножать.
    [​IMG]
    Попробуйте самостоятельно решить примеры на сложение и вычитание в шестнадцатеричной, восьмеричной и двоичной системах представления чисел.
    [​IMG]
    Задание #11: Попробуйте делить и умножать в этих системах представления чисел. Производите побольше действий в уме, развивайте свои способности быстро считать, запоминать информацию.
    Программа hiew позволяет вывести на экран дамп файла. Программа debug.exe имеет команду d, выводящую на экран дамп (dump) памяти. Даже Norton Commander позволяет по F4 выводить содержимое файла в шестнадцатеричном виде.
    Теперь вы должны очень хорошо представлять себе и чувствовать шестнадцатеричную и другие системы. Наконец-то вы сможете разобраться в дампе.
    Существуют специальные шестнадцатеричные калькуляторы, позволяющие считать в этих широкораспространенных системах представления чисел.
     

    Вложения:

    • 44.png
      44.png
      Размер файла:
      5,8 КБ
      Просмотров:
      4.130
    • 43.png
      43.png
      Размер файла:
      2,7 КБ
      Просмотров:
      4.050
    • latex1.gif
      latex1.gif
      Размер файла:
      516 байт
      Просмотров:
      1.178
    • latex2.gif
      latex2.gif
      Размер файла:
      998 байт
      Просмотров:
      1.215
    rasstriga, galenkane, Коцит и ещё 1-му нравится это.
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709

    Несколько приемов, которые упростят перевод из двоичного в десятеричное представление


    1. [math]2^n = 1\overbrace{000\cdots 00}^{n}[/math][math](n+1)[/math]-разрядное двоичное число в котором [math]n[/math] нулей
    2. чему равно [math]2^0+2^1+2^2+\cdots +2^{n-2}+2^{n-1}=?[/math] перед нами сумма [math]n[/math] первых членов геометрической прогрессии, где каждый следующий член прогрессии больше предыдущего в 2 раза. Любой член геометрической прогрессии может быть вычислен по формуле: [math]b_{n}=b_{1}\times q^{n-1}[/math] Формула суммы [math]n[/math]-первых членов геометрической прогрессии [math]S_{n}=\frac{b_{1}\times (1-q^{n})}{1-q}[/math]
      В нашем случае [math]b_1=2^0=1[/math] [math]q=2[/math] [math]S_n=2^n-1[/math]
      [math]2^0+2^1+2^2+\cdots +2^{n-2}+2^{n-1}=2^n-1[/math] то есть [math]n[/math]-разрядное двоичное число только из единиц соответствует десятичному числу [math]\overbrace{111\cdots 11}^{n}=2^n-1[/math]
    3. [math]n[/math]-разрядное двоичное число из чередующихся нулей и единиц, заканчивающееся на единицу, соответствует десятичному числу [math]\overbrace{1.01.01.01\cdots 01.01}^{n}=\frac{1}{3}(2^{n+1}-1)[/math]
      [math]2^{n+1}[/math] потому что [math]\overbrace{1.01.01.01\cdots 01.01}^{n}=\overbrace{01.01.01.01\cdots 01.01}^{n+1}[/math]
    4. [math]n[/math]-разрядное двоичное число из чередующихся нулей и единиц, заканчивающееся на ноль, соответствует десятичному числу [math]\overbrace{10.10.10\cdots 10.10}^{n}=\frac{2}{3}(2^{n}-1)[/math]
    5. [math]n[/math]-разрядное двоичное число из чередующихся двух единиц и нуля, заканчивающееся на ноль, соответствует десятичному числу [math]\overbrace{110.110.110\cdots 110}^{n}=\frac{6}{7}(2^{n}-1)[/math]
    6. [math]n[/math]-разрядное двоичное число из чередующихся единицы и двух нулей, заканчивающееся на ноль, соответствует десятичному числу [math]\overbrace{100.100.100\cdots 100}^{n}=\frac{4}{7}(2^{n}-1)[/math]
    7. Интересно, заметили ли Вы связь между числителем и знаменателем дроби, стоящей перед [math](2^{n}-1)[/math] и повторяющейся частью и периодичностью, с которой эта часть повторяется?:)
    8. вычислим чему равно произведение [math](2+1)(2^{2}+1)(2^{4}+1)\cdots (2^{2^n}+1)=?[/math] Думаете это сложно и нужен калькулятор? Внимание на экран [math]2+1=3=4-1=2^2-1[/math] и [math](a+b)(a-b)=a^2-b^2[/math] тогда
      [math](2+1)(2^{2}+1)(2^{4}+1)\cdots (2^{2^n}+1)=[/math]
      [math]=(2^{2}-1)(2^{2}+1)(2^{4}+1)\cdots (2^{2^{n}}+1)=[/math]
      [math]=(2^{4}-1)(2^{4}+1)\cdots (2^{2^{n}}+1)=\cdots =[/math]
      [math]=(2^{2^{n}}-1)(2^{2^{n}}+1)=2^{2^{n+1}}-1[/math]
    9. А теперь умножим [math]\overbrace{111\cdots 11}^{n}=2^n-1[/math] на [math]2^m[/math] В результате получится
      [math](2^n-1)\cdot 2^m=2^{n+m}-2^m=\underbrace{\overbrace{11\cdots 11}^{n}\overbrace{000\cdots 00}^{m}}_{n+m}[/math][math](n+m)[/math]-разрядное двоичное число, в котором [math]n[/math] единиц и [math]m[/math] нулей.
      В разделе «Алгоритм Содена» переводят двоичное число 11111100012 в десятичное 100910, но можно же сделать и вот так [math]1111110001_{2}=2^{10}-2^{4}+1=1024-16+1=1009_{10}[/math]:)
    10. Целая часть от [math]\underbrace{\sqrt{111\cdots 11}}_{2n}=\underbrace{111\cdots 11}_{n}[/math]
    11. [math]11^2=3^2=9=1001[/math]
      [math]111^2=7^2=49=110001[/math]
      [math]11111^2=31^{2}=961=1111000001[/math]
      [math](2^{n}-1)^2=2^{2n}-2\cdot 2^{n}+1=2^{2n}-2^{n+1}+1[/math]
      [math]{\underbrace{11\cdots 11}_n}^2=\underbrace{11\cdots 11}_{n-1}{\overbrace{000\cdots 00}^n} 1[/math]

    Числа со знаком

    Прямой (знаковеличинный) код

    Рано или поздно возникает потребность представлять в двоичном коде отрицательные числа. А как в двоичной системе представить отрицательное число, если мы не можем использовать для это цели минус как в традиционной десятичной системе? Самое простое — отвести один разряд (скажем, старший) под знак числа, используя остальные для представления величины числа. Этот способ называется знаковеличинным или прямым кодом и соответствует обычной записи числа со знаком. Он используется при выводе чисел на индикацию, в АЦП (аналого-цифровых преобразователях), для представления вещественных и двоично-десятичных чисел. В такой кодировке появляются нули двух типов (+0 и -0)

    Смещенный код

    Второй способ представления числа со знаком — представление числа в виде смещенного кода. Для получения смещенного кода какого-либо числа, нужно к этому числу, представленному в прямом коде, прибавить половину наибольшего возможного числа. Благодаря этой операции последовательность всех чисел, начиная со старшего отрицательного и заканчивая старшим положительным, будет представлять из себя простую двоичную прогрессию. Информацию о знаке числа здесь также несет старший разряд, нуль становится единственным. Смещенный код используется в АЦП и ЦАП (цифро-аналоговых преобразователях), в смещенном коде представляется степень вещественного числа.

    Дополнительный код

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

    Таблица #4. 4-разрядные двоичные числа, представленные в трех системах
    деся-
    тичное
    представ-
    ление
    числа
    двоичное представление числа
    прямой
    код
    смещен-
    ный
    код
    дополни-
    тельный
    код
    +7​
    0111​
    1111​
    0111​
    +6​
    0110​
    1110​
    0110​
    +5​
    0101​
    1101​
    0101​
    +4​
    0100​
    1100​
    0100​
    +3​
    0011​
    1011​
    0011​
    +2​
    0010​
    1010​
    0010​
    +1​
    0001​
    1001​
    0001​
    0​
    0000​
    1000​
    0000​
    -0​
    1000​
    —​
    —​
    -1​
    1001​
    0111​
    1111​
    -2​
    1010​
    0110​
    1110​
    -3​
    1011​
    0101​
    1101​
    -4​
    1100​
    0100​
    1100​
    -5​
    1101​
    0011​
    1011​
    -6​
    1110​
    0010​
    1010​
    -7​
    1111​
    0001​
    1001​
    -8​
    —​
    0000​
    1000​
     

    Вложения:

    • 0.png
      0.png
      Размер файла:
      57,3 КБ
      Просмотров:
      4.175
    • 0.png
      0.png
      Размер файла:
      2,7 КБ
      Просмотров:
      4.085
    • 0.png
      0.png
      Размер файла:
      46,6 КБ
      Просмотров:
      1.037
    • 0.png
      0.png
      Размер файла:
      1,2 КБ
      Просмотров:
      4.064
    Последнее редактирование: 30 июн 2019
    rasstriga, rococo795 и galenkane нравится это.
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    В таблице #4 видно, числа в дополнительном коде отличаются от чисел в смещенном коде инверсным значением старшего значащего разряда (СЗР). Точно также, как и при других формах представления, СЗР несет информацию о знаке. Здесь имеется только один ноль, представляемый нулевыми состояниями всех разрядов.

    Более подробно о дополнительном коде

    По определению, для каждого натурального числа [math]n[/math] существует одно и только одно отрицательное число, обозначаемое [math]-n[/math], которое дополняет [math]n[/math] до нуля:
    [math]n + (-n) = 0.[/math]
    Найдем такое 4-битное число, которое при сложении с числом 5 (0101) дало бы нам ноль, переносом в 5-й бит мы пренебрегаем.
    [​IMG]
    Теперь самостоятельно заполните таблицу #5
    Таблица #5
    hex-
    число
    двоичное число
    n-n
    00000
    10001
    20010
    30011
    40100
    501011011
    60110
    70111
    81000
    91001
    A1010
    B10110101
    C1100
    D1101
    E1110
    F1111
    Так как [math]n = -(-n)[/math], поэтому, таблицу #5 можно сократить в два раза
    Таблица #6
    число nчисло -n
    HexbinHexbin
    0​
    0000​
    0​
    0000​
    1​
    0001​
    F​
    1111​
    2​
    0010​
    E​
    1110​
    3​
    0011​
    D​
    1101​
    4​
    0100​
    C​
    1100​
    5​
    0101​
    B​
    1011​
    6​
    0110​
    A​
    1010​
    7​
    0111​
    9​
    1001​
    8​
    1000​
    8​
    1000
    При этом оказалось, что числа 0 и 8 являются сами для себя отрицательными числами. Если не рассматривать числа 0 и 8, числа в левой половине таблицы объединяет то, что самый старший (четвертый) бит у них равен 0, а у чисел в правой половине самый старший бит равен 1. Пусть самый старший бит считается знаковым. Если он равен 0, число будем считать положительным, если 1 — отрицательным. Мы только что изобрели способ представления положительных и отрицательных чисел в двоичной системе, так называемый «код дополнения до двух», или «дополнительный код». При этом, число 0 может быть только положительным, а четырехбитовое число 8 — только отрицательным.
    Таблица #7
    Положительное
    4-битное число n
    Отрицательное
    4-битное число -n
    десятич-
    ное
    hexbinдесятич-
    ное
    hexbin
    +0​
    0​
    0000​
    -0​
    —​
    —​
    +1​
    1​
    0001​
    -1​
    F​
    1111​
    +2​
    2​
    0010​
    -2​
    E​
    1110​
    +3​
    3​
    0011​
    -3​
    D​
    1101​
    +4​
    4​
    0100​
    -4​
    C​
    1100​
    +5​
    5​
    0101​
    -5​
    B​
    1011​
    +6​
    6​
    0110​
    -6​
    A​
    1010​
    +7​
    7​
    0111​
    -7​
    9​
    1001​
    +8​
    —​
    —​
    -8​
    8​
    1000
    Компьютер различает целые числа без знака (неотрицательные) и целые числа со знаком. Положительные и отрицательные числа расположены как бы в «кольце». Если вычитать в цикле из байтовой переменной на каждом шаге единицу, то, когда значение переменной достигнет нуля, следующим вычитанием мы получим в переменной значение FF16=25510 — максимальное беззнаковое число, которое может быть записано в байт, и одновременно значение -1, если рассматривать его, как число со знаком. При продолжающемся вычитании мы проходим весь диапазон отрицательных чисел и достигаем минимального значения, которое может быть записано в байт — 8016=-12810. На следующем шаге мы получаем значение 7F16=+12710 — максимальное знаковое число, которое может быть записано в байт. Если продолжить вычитание — мы опять достигаем значение нуля.
    [​IMG]
    Таблица #8. Дополнительный код
    дополни-
    тельный
    двоичный
    код
    Hexчисло со
    знаком
    число без
    знака
    0000 0000​
    0​
    0​
    0​
    0000 0001​
    1​
    1​
    1​
    0000 0010​
    2​
    2​
    2​
    . . . .​
    0111 1111​
    7F​
    127​
    127​
    1000 0000​
    80​
    -128​
    128​
    1000 0001​
    81​
    -127​
    129​
    . . . .​
    1111 1110​
    FE​
    -2​
    254​
    1111 1111​
    FF​
    -1​
    255​
    Для целых чисел со знаком положительное число записывается в прямом коде (как есть). Отрицательное — в дополнительном коде. Преобразовать положительное число в отрицательное можно пятью способами.
    Способ первый — классический:
    1. взять число в прямом коде, преобразовать его в инверсный код. Для этого все нули этого числа необходимо заменить на единицы, а единицы на нули.
    2. К числу в инверсном коде добавить 1.
    На рисунке пример преобразования числа +7 в –7.
    [​IMG]
    Способ второй — взять число, отнять от него единицу, преобразовать в двоичный вид, заменить нули на единицы, а единицы на нули. 7-1 = 6 = 0000 0110 → 1111 1001 = -7
    Способ третий — быстрый: двигаемся справа налево и пропускаем нули до первой единицы, после нее заменяем единицы на нули, а нули на единицы. 20 = 0001 0100 → 1110 1100 = -20
    Способ четвертый — практический: чтобы получить n-разрядное отрицательное число возьмем число [math]2^N[/math](для байта [math]2^8 = 256[/math], для слова [math]2^{16}=65536[/math], для двойного слова [math]2^{32}=4294967296[/math], для учетверенного cлова [math]2^{64}=18446744073709551616[/math]) и отнимем от него наше число, получившееся число преобразуем в двоичный или hex-код:
    256 – 7 = 249 = 1111 1001 = F9 = – 7.

    [​IMG]
    Способ пятый — студенческий: щелкаем по клавише «Пуск», открываем стандартные приложения, запускаем калькулятор в режиме «Программист», теперь щелкаем по клавише 7 и «+/–» на экранчике калькулятора появится –7. А теперь жмем на клавишу F8 или мышкой по переключателю с надписью «Bin». Что мы видим на экране калькулятора? Число 1111111111111111111111111111111111111111111111111111111111111001. Многовато, на экране — учетверенное слово. Жмем на F4 или мышью по переключателю с надписью «1 байт». Наше число приобрело нормальный вид 11111001b.
    На самом деле, нет необходимости пересчитывать отрицательные числа. Вы пишете –7, а транслятор автоматически подставит туда, где нужно число 11111001b.
    Если мы пренебрегаем знаковым разрядом, то диапазон чисел увеличивается в 2 раза: [math]2^7 = 128[/math]; [math]2^8 = 256[/math]
     

    Вложения:

    • 0.jpg
      0.jpg
      Размер файла:
      22,6 КБ
      Просмотров:
      3.867
    Последнее редактирование: 19 фев 2023
    mantissa, rasstriga, rococo795 и ещё 1-му нравится это.
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709

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

    У десятичных чисел каждая позиция числа соответствует степени числа 10, то есть число [math]1234,56=1\cdot 10^3+2\cdot 10^2+3\cdot 10^1+4\cdot 10^0+5\cdot 10^{-1}+6\cdot 10^{-2}[/math].
    Запятая показывает границу между позицией, соответствующей [math]10^0[/math], и дробной частью. В дробной части позиции числа также являются степенями числа 10, но эти степени теперь отрицательные. Дробные двоичные числа записываются аналогично дробным десятичным, но основание системы счисления здесь 2, а не 10. Например,[math]1,101_2=1+\frac{1}{2}+\frac{1}{8}=1\frac{5}{8}=1,625[/math]
    Чтобы получить эквивалент целого числа в двоичной системе, мы использовали последовательное деление на 2. Чтобы получить эквивалент десятичной дроби, используем обратную операцию — последовательное умножение на 2.
    Для перевода десятичной дроби в двоичную систему можно использовать четыре способа, а уж который из них Вам покажется более удобным — выбирайте сами.
    Способ первый. Дробную часть числа последовательно умножают на 2 пока либо дробная часть не станет равной нулю, либо не будет получено необходимое количество разрядов. Целые значения, получаемые при умножении, будут являться эквивалентом десятичной дроби в двоичной системе. Посмотрите конкретный пример
    [​IMG]
    Способ второй. Умножать на два 8 раз чтобы получить 8-двоичных разрядов дробной части долго и утомительно. А давайте 0,14159 умножим сразу на [math]2^8=256[/math], что получится? [math]0,14159\times 256=36,2470410=100100_2[/math]. 100100 это шесть разрядов, а если добавить 2 нуля слева? 00100100 ничего не напоминает? Добавим "0," и "0,00100100" двоичный эквивалент числа 0,14159. Нужно получить 16 разрядов после запятой? Смело умножайте на [math]2^{16}=65536[/math], переводите в двоичный вид и не забудьте добавить недостающие нули слева.
    Способ третий. Любое дробное двоичное число можно представить как
    [math]x_1\cdot 0,5 + x_2\cdot 0,25 + x_3\cdot 0,125 +\cdots[/math]
    где [math]x_1, x_2,\cdots x_n[/math] — нули или единицы, то есть [math]0,1_{10}=0,0001100_2[/math].
    Способ четвертый. Переведем в двоичную систему, например, число [math]0,27=\frac{27}{100}[/math]. Ближайшая к 100 степень двойки [math]2^7=128[/math].
    [math]\frac{27}{100}\times\frac{1,28}{1,28}=\frac{34,56}{128}=\frac{32+2+1}{128}=\frac{1}{4}+\frac{1}{64}+\frac{1}{128}=2^{-2}+2^{-6}+2^{-7}=[/math]
    [math]=0,01+0,000001+0,0000001=0,0100011_2[/math]
    Перевод десятичного дробного числа 0,406 в шестнадцатеричную систему делается аналогично переводу к двоичному виду:
    [​IMG]
    [math]0,616\times 16=9,856[/math] и так далее, то есть [math]0,406_{10}=0,67EF9..._{16}[/math] .
    Для перевода вещественного целого числа в двоичную или шестнадцатеричную систему необходимо целую и дробную часть перевести по отдельности в двоичную или шестнадцатеричную систему, а затем соединить их. Например, число [math]\pi[/math] равное [math]3,14159[/math] должно выглядеть вот так [math]11,00100100_2[/math], или так [math]3,243F_{16}[/math].
    Существует два способа записи вещественных чисел:
    Первый способ — целая часть числа отделяется от дробной символом запятой, расположенной между конкретными разрядами в фиксированной позиции. Такой способ записи называют представлением вещественных чисел с фиксированной запятой. Возьмем 16 разрядное число и отведем под целую часть числа 8 разрядов, а под дробную 8 разрядов, тогда максимально большое число, которое можно записать таким способом:[math]11111111,11111111_2=255,99609375 \approx 256[/math], а минимальное возможное число — [math]00000000,00000001_2=\frac{1}{256} \approx 0,00390625[/math]. Запомните эти числа.
    Второй способ применяется в астрономии, физике, химии, математике для записи очень больших либо очень маленьких чисел. Например, скорость света в вакууме составляет около [math]300000000[/math] м/с, а гравитационная постоянная примерно равна [math]0,0000000000667[/math] Нм2/кг2. Для удобства работы с такими числами используют так называемую экспоненциальную форму записи. Вместо [math]300000000[/math] пишут [math]3\cdot 10^8[/math], а вместо [math]0,0000000000667[/math][math]6,67\cdot 10^{-11}[/math]. Любое число представляется в виде [math]\pm C,M\cdot R^P[/math], где [math]C[/math] — целая часть числа, дробную часть числа представляющую значащие разряды — [math]M[/math], называют мантиссой. [math]R[/math] — основание системы счисления. [math]P[/math] — показатель степени, определяющий на сколько разрядов вправо или влево необходимо переместить запятую в мантиссе, называется порядком числа. Число [math]C[/math] должно быть [math]1\le C < R[/math]. Такой способ записи называют представлением вещественных чисел с плавающей запятой. Как и в первом случае возьмем 16-разрядное число. Под мантиссу отведем 8 разрядов и 8 разрядов под порядок числа (из 8 разрядов 1 разряд отводится под знак и 7 разрядов под число), в этом случае максимальновозможное число [math]2^{127}\approx 10^{38}[/math], а минимальновозможное — [math]2^{–127}\approx 10^{–38}[/math]. Сравните их с числами полученными в первом случае :)
    Для представления в компьютере дробного числа первый разряд числа считается знаковым и обозначает знак мантиссы. За ним следует мантисса (число со значением больше или равным 1 и меньшим 2) и порядок (степень числа 2). Представление чисел в виде мантиссы и порядка позволяют сводить умножение и деление чисел к сложению и вычитанию показателей степеней, а возведение в степень и извлечение корня — к умножению и делению на показатель степени, что упрощает и сокращает сложные вычисления.
    Вещественные числа в памяти компьютера хранятся в нормализованном виде, то есть оно обязательно должно иметь следующий вид:
    [math](-1)^S\times 1,M\times 2^P[/math],​
    где значение [math]S[/math] определяет знак ([math]S=0[/math] — число положительное, [math]S=1[/math] — отрицательное), [math]M[/math] — двоичная мантисса числа, [math]P[/math] — порядок двоичного числа.
    Из-за того, что целая часть вещественного числа в двоичной системе всегда равна 1, его, для увеличения разрядности дробной части, предпочитают «хранить в уме».
    Для упрощения вычислений значение порядка хранят не в дополнительном коде (то есть не в виде целого со знаком), а в смещенном коде в виде суммы с некоторым числом, это позволяет облегчить сравнение вещественных чисел — в большинстве случаев достаточно сравнить их экспоненты.
    Обратите внимание, что в смещенном порядке у отрицательных чисел и нуля в двоичном представлении старший разряд нулевой. В смещенном коде число суммируется с константой, которая для N-битного кода равна [math]2^{N-1}-1[/math].
    Десятичное
    значение
    Смещенный код
    8-битный11-битный15-битный
    -16383​
    —​
    —​
    0000h​
    -1023​
    —​
    000h​
    3C00h​
    -127​
    00h​
    380h​
    3F80h​
    . . .​
    -1​
    7Eh​
    3FEh​
    3FFEh​
    0​
    7Fh​
    3FFh​
    3FFFh​
    1​
    80h​
    400h​
    4000h​
    . . .​
    128​
    0FFh​
    47Fh​
    407Fh​
    1024​
    —​
    7FFh​
    43FFh​
    16384​
    —​
    —​
    7FFFh​
    Микропроцессоры семейства x86 х64 могут работать с 32/64/80-битными вещественными числами (одинарная/двойная/повышенная точность), а также со 128-битными, состоящими из четырех упакованных вещественных чисел одинарной точности.
    Коли-
    чество
    бит
    ТипПоле
    знака
    Поле
    порядка
    КонстантаПоле
    мантиссы
    Диапазон принимаемых значений
    32​
    REAL4​
    1 бит​
    8 бит​
    27-1=127​
    23 бита​
    От [math]\pm 1,18\cdot 10^{-38}[/math] до [math]\pm 3,4\cdot 10^{38}[/math]
    64​
    REAL8​
    1 бит​
    11 бит​
    210-1=1023​
    52 бита​
    От [math]\pm 2,23\cdot 10^{-308}[/math] до [math]\pm 1,79\cdot 10^{308}[/math]
    80​
    REAL10​
    1 бит​
    15 бит​
    214-1=16383​
    64 бита​
    От [math]\pm 3,37\cdot 10^{-4932}[/math] до [math]\pm 1,18\cdot 10^{4932}[/math]
    Число 193,75 в формате вещественного числа, занимающего два слова:
    [math]193,75\to 4341C000_{16}[/math]
    [math]193,75>0 \to[/math] знак=0
    [math]log_{2}(193,75)=7,598053[/math]
    степень [math]7+127=134=10000110_2[/math]
    разрядов в мантиссе - степень [math]23-7=16[/math]
    мантисса [math](193,75-2^{7})\cdot 2^{16}=66,75\cdot 2^{16}=66,75\cdot 65536=4374528=10000101100000000000000_2[/math]

    Преобразуем вид число в бинарное представление:
    01000011010000011100000000000000Знак числа 0=«+» 1=«—»
    01000011010000011100000000000000Порядок 86h=+7 в смещенном коде [math]10000110_2=134_{10}=7+127[/math]
    01000011010000011100000000000000мантисса числа=[math](1),1000001110000_2[/math]
    [​IMG]
    Рис. Форматы представления вещественных чисел​
     

    Вложения:

    • 00.png
      00.png
      Размер файла:
      32,1 КБ
      Просмотров:
      3.930
    • 01.png
      01.png
      Размер файла:
      39,8 КБ
      Просмотров:
      3.948
    • 02.png
      02.png
      Размер файла:
      112,6 КБ
      Просмотров:
      4.268
    rasstriga, galenkane, shufps и ещё 1-му нравится это.
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Запись одного и того же числа в разных представлениях, естественно, будет отличаться. Число 193,75 может быть представлено как:
    Коли-
    чество
    бит
    Типшестнадцатеричное представление числа 193,75
    32REAL44341C000h
    64REAL84068380000000000h
    80REAL104006C1C0000000000000h
    Преобразуем число 4068380000000000h в бинарное представление:
    0100.0000.0110.1000.0011.1000.0000.0000.0000.0000.0000.0...0.0000.0000.0000.0000
    Знак числа 0=«+»
    010000000110100000111000000000000000000000000...00000000000000000
    Порядок =+7 [math]10000000110_2=1030_{10}=7+1023[/math]
    010000000110100000111000000000000000000000000...00000000000000000
    мантисса числа=(1),1000001110000000000000000000000000...000000000000b
    Преобразуем число 4006C1C0000000000000h в бинарное представление:
    0100000000000110110000011100000000000000000000000000000000...0000
    Знак числа 0=«+»
    0100000000000110110000011100000000000000000000000000000000...0000
    Порядок =+7 [math]100000001100000_2=16480_{10}=7+16383[/math]
    0100000000000110110000011100000000000000000000000000000000...0000
    мантисса числа=1,10000011100000000000000000000000000000000...0000b
    Типы REAL4, REAL8 и REAL10 соответствуют стандартным вещественным типам в Pascal/Delphi и C/C++
    AsmPascal/DelphiC/C++Формула
    REAL4Singlefloat[math](-1)^{S}\times(1+m\times 2^{-23})\times 2^{P-127}[/math]
    REAL8Doubledouble[math](-1)^{S}\times(1+m\times 2^{-52})\times 2^{P-1023}[/math]
    REAL10Extendedlong double[math](-1)^{S}\times m\times 2^{P-16446}[/math]
    Первые два типа (REAL4 и REAL8) являются «упакованными», а REAL10 — «неупакованным» типом, в нем старший, всегда единичный, бит нормализованной мантиссы хранится в явном виде. Все вычисления внутри FPU происходят после автоматического преобразования типов REAL4 и REAL8 в REAL10.
    Для записи вещественного числа в программе пересчет вещественного десятичного числа из десятичной системы в hex или двоичную самому делать не обязательно, просто запишите число, используя в качестве разделителя точку вместо запятой:
    Код (ASM):
    1. pi dt 3.1415926535897932384626433832795
    А компилятор сам подставит
    • 32-битный эквивалент в случае с директивой dd
    • 64-битный для директивы dq
    • 80-битный для директивы dt
    Перевожу 193,75
    • в REAL4 (мантисса 23 бита, степень смещается на 127)
      вычисляем степень [math]log_2(193{,}75)=7{,}598053[/math] округляем в меньшую сторону 7. [math]p=127+7=134=86_{16}[/math]
      (193,75-27)x 223-7=(193,75-128)x 65536=4308992=41C00016
      [math]\underbrace{0.100}_{4}\underbrace{0 011}_{3}\underbrace{0.100}_{4}\underbrace{0001}_{1}\underbrace{1100}_{C}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}[/math]
    • в REAL8 (мантисса 52 бита, степень смещается на 1023)
      [math]p=1023+7=1030=406_{16}[/math]
      (193,75-27)x 252-7=2313372464840704=838000000000016
      [math]\underbrace{0.100}_{4}\underbrace{0 000}_{0}\underbrace{0110.}_{6}\underbrace{1000}_{8}\underbrace{0011}_{3}\underbrace{1000}_{8}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}[/math]
    • в REAL10 (мантисса 63 бита, степень смещается на 16383)
      [math]p=16383+7=16390=4006_{16}[/math]
      193,75 x 263-7=13961158844848537600=C1C000000000000016
      [math]\underbrace{0.100}_{4}\underbrace{0 000}_{0}\underbrace{0000}_{0}\underbrace{0110.}_{6}\underbrace{1{,}100}_{С}\underbrace{0001}_{1}\underbrace{1100}_{С}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}\underbrace{0000}_{0}[/math]
    Задание #12: Теперь читателю предлагается потренироваться в переводе чисел. Пред вами два простых примера: 0.125 и 0.625. Можно усложнить их: 23.125 и 456.625. Проверьте свои ответы, записав результат в переменную типа dword и посмотрите под отладчиком число в стеке FPU.
     
    Последнее редактирование: 19 июн 2019
    rasstriga, galenkane и rococo795 нравится это.
  9. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709

    Специальные численные значения


    ЗнакПорядок
    (79-64 биты)
    Мантисса
    (63-0 биты)
    Название числа
    0​
    000...00000000000...00000000000
    +0​
    1​
    111...11111111111...11111111111
    -0​
    0​
    111...11111111000...00000000000
    [math]+\infty[/math] (+бесконечность)​
    1​
    111...11111111000...00000000000
    [math]-\infty[/math] (-бесконечность)​
    [math]x[/math]
    000...00000000[math]xxx...xxxxxxxx[/math]Денормализованные числа, используются для работы
    с очень маленькими числами от [math]\pm 10^{-4932}[/math] до [math]\pm 10^{-16445}[/math]
    [math]x[/math]
    111...1111111110[math]x...xxxxxxxx[/math]Нечисло типа SNAN (Signal Non A Number). Среди [math]x[/math] есть
    единицы. FPU реагирует на появление SNAN возбуждением
    исключения недействительной операции
    Несмотря на большой диапазон вещественных значений, представимых в регистрах данных FPU, значения, например, [math]+\infty[/math] и [math]-\infty[/math] находятся за пределами этого диапазона. Для того, чтобы иметь возможность реагировать на некоторые вычислительные ситуации, которые могут возникнуть в результате математических операций в блоке FPU, предусмотрены специальные комбинации битов, называемые специальными численными значениями. Над специальными численными значениями можно выполнять некоторые операции. Программист может и сам кодировать специальные численные значения директивой DT (х – любое значение бита).
    Если в результате вычислений мантисса и порядок равны нулю, то, несмотря на скрытую единицу в целой части числа REAL4/8, все число полагается равным нулю. Любой конечный результат операции FPU, который из-за ограниченности поля порядка не может быть представлен в 23/52/64 разрядах для REAL4/8/10, соответственно вызывает особый случай некорректности представления числа.
     
    Последнее редактирование: 19 фев 2023
    rasstriga и rococo795 нравится это.
  10. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Как быстро перевести вещественное число в десятичном виде в REAL4, REAL8, REAL10
    Коли-чество
    бит
    ТипПоле
    знака
    Поле
    порядка
    КонстантаЦелая
    часть
    Поле
    мантиссы
    Диапазон принимаемых значений
    32​
    REAL4​
    1 бит​
    8 бит​
    [math]2^{8-1}-1=127[/math]
    скрыта​
    23 бита​
    От ± 1,18x10-38 до 3,4x1038
    64​
    REAL8​
    1 бит​
    11 бит​
    [math]2^{11-1}-1=1023[/math]
    скрыта​
    52 бита​
    От ± 2,23x10-308 до 1,79x10308
    80​
    REAL10​
    1 бит​
    15 бит​
    [math]2^{15-1}-1= 16383[/math]
    явно
    указана​
    63 бита​
    От ± 3,37x10-4932 до 1,18x104932
    Представить число -240,9375 в формате REAL4
    1. -240,9375 < 0 → Знак=1
    2. log2(240,9375)=7,912515145→ степень =7
      степень в смещенном виде 7+127=134=1000.0110b
    3. 23 разряда (мантисса) - 7 (степень) = 16
    4. мантисса
      216×(240,9375-27)=7401472=70F000h=111.0000.1111.0000.0000.0000b
    знакстепеньмантисса
    bin
    1​
    100​
    0011​
    0​
    111​
    0000​
    1111​
    0000​
    0000​
    0000​
    hex
    C​
    3​
    7​
    0​
    F​
    0​
    0​
    0​
    Представить число 15,92 в формате REAL8
    1. 15,92>0 → Знак=0
    2. log2(15,92)=3,992768431 → степень = 3
      степень в смещенном виде 3+1023=1026=100.0000.0010b
    3. 52 разряда (мантисса) - 3 (степень) = 49
    4. мантисса
      249×(15,92-23)=249×7,92=4458563631096791,04~4458563631096791=FD70A3D70A3D7h=
      =1111.1101.0111.0000.1010.0011.1101.0111.0000.1010.0011.1101.0111b
    15,92=402FD70A3D70A3D7
    знакстепеньмантисса
    bin
    0​
    100​
    0000​
    0010​
    1111​
    1101​
    0111​
    0000​
    1010​
    0011​
    1101​
    0111​
    0000​
    1010​
    0011​
    1101​
    0111​
    hex
    4​
    0​
    2​
    F​
    D​
    7​
    0​
    A​
    3​
    D​
    7​
    0​
    A​
    3​
    D​
    7​
    Представить число 6,1429 в формате REAL10
    1. 6,1429>0 → Знак=0
    2. log2(6,1429)=2,61892 → степень = 2
      степень в смещенном виде 2+16383=16385=100.0000.0000.0001b
    3. 63 разряда (мантисса) - 2 (степень) = 61
    4. мантисса
      261×6,1429=14164563021298800577,7408~14164563021298800578=C492A305532617C2h=
      =1100.0100.1001.0010.1010.0011.0000.0101.0101.0011.0010.0110.0001.0111.1100.0010b
    6,1429=4001C492A305532617C2
    знакстепеньцелая
    часть
    мантисса
    bin
    0​
    100​
    0000​
    0000​
    0001​
    1​
    100​
    0100​
    1001​
    0010​
    1010​
    0011​
    0000​
    0101​
    0101​
    0011​
    0010​
    0110​
    0001​
    0111​
    1100​
    0010​
    hex
    4​
    0​
    0​
    1​
    C​
    4​
    9​
    2​
    A​
    3​
    0​
    5​
    5​
    3​
    2​
    6​
    1​
    7​
    C​
    2​
    Какому числу типа float соответствует 8027B2A6h=1000.0000.0010.0111.1011.0010.1010.0110b ?
    знакстепеньмантисса
    1000.0000.0010.0111.1011.0010.1010.0110
    -
    0​
    2601638​
    степень нулевая, значит число денормализованное, то есть целая часть равна нулю
    Какому числу типа double соответствует запись C06E4D1000000000?
    знакстепеньмантисса
    bin
    1​
    100​
    0000​
    0110​
    1110​
    0100​
    1101​
    0001​
    0000​
    0000​
    0000​
    0000​
    0000​
    0000​
    0000​
    0000​
    0000​
    hex
    C​
    0​
    6​
    E​
    4​
    D​
    1​
    0​
    0​
    0​
    0​
    0​
    0​
    0​
    0​
    0​
    1. вычисляем знак
      знак=1 [​IMG] число <0
    2. порядок 100000001102=103010
      вычисляем степень 1030-1023=7
    3. обрабатываем мантиссу
      52(разрядов в мантиссе)-7(степень)=45
      11100100110100010000000000000000000000000000000000002=402538078876467210
      4025380788764672/245=4025380788764672/35184372088832=114,408203125
      114,408203125+27=114,408203125+128=242,408203125
    4. учтем, что число отрицательное
      результат: -242,408203125
    Из шестнадцатеричного представления получить десятичное число
    дана шестнадцатеричная свертка 2F16F10016=0010.1111.0001.0110.1111.0001.0000.00002
    знак.порядок.мантисса=0.01011110.00101101111000100000000
    знак=0 --> число положительное
    порядок 010111102=9410 степень 94-127=-33
    мантисса 1.001011011110001000000002=989209610
    число (9892096*2-23)*2-33= 9892096*2-56=9892096/72057594037927936=
    =+1,3728040926253015641123056411743*10-10
    или вот так
    мантисса 001011011110001000000002=150348810
    число (1503488*2-23+1)*2-33=(1503488+223)*2-23-33=(1503488+8388608)/72057594037927936=+1,3728040926253015641123056411743*10-10
    Формула для расчета денормализованных чисел
    REAL4(-1)знак ×2-149× мантисса
    REAL8(-1)знак ×2-1074× мантисса
    REAL10(-1)знак ×2-16445× мантисса
    [math]F=(-1)^{sign}\cdot 2^{-149} \cdot mantiss =-1 \cdot 2^{-149} \cdot 01001111011001010100110=[/math]
    [math]=-2601638\cdot 1,4012984643248170709237295832899\cdot 10^{-45} =[/math]
    [math]=-3,6456713341290884347638699856112\cdot 10^{-39}[/math]
    FPU ХАКИ
    FPU Hacks, когда вычисления делают приближенно через integer типы. (Естественно это либо через память, либо если FP регистры позволяют делать integer операции над ними.
    Быстрая конвертация в Integer
    Код (C):
    1. int  FastFloatToInt(float f)
    2. {
    3.     f += (float)(3 << 21);
    4.     return (*((int*) &f) - 0x4ac00000) >> 1;
    5. }
    Быстрый квадратный корень
    Ошибка при вычислении не превышает 5%
    Код (C):
    1. float FastSqrt(float f)
    2. {
    3.     int t = *(int*) &f;
    4.     t -= 0x3f800000;
    5.     t >>= 1;
    6.     t += 0x3f800000;
    7.     return *(float*)&t;
    8. }

    Approximations that depend on the floating point representation


    Вещественное число представляется в формате [math]m\times 2^{p}[/math] Квадратный корень равен [math]\sqrt {m}\times 2^{(\frac{p}{2})}[/math] аналогичные формулы применимы для кубических корней и логарифмов. На первый взгляд, это не упрощает вычисление квадратного корня, но предположим, что требуется только приближение: тогда просто [math]2^{(\frac{p}{2})} [/math] хорошо на порядок. Некоторые степени [math]p[/math] будут нечетными, поэтому при вычисления квадратного корня например от числа 3141.59 = 3.14159×103 вместо того, чтобы иметь дело с дробными степенями основания, умножаем мантиссу на основание и вычитаем единицу от степени, чтобы сделать степень четной. Скорректированное представление станет эквивалентом [math]\sqrt{31.4159×10^{2}} = \sqrt{31.4159}\times 10^{1}[/math].
    Если берется целая часть скорректированной мантиссы, могут быть только значения от 1 до 99, и их можно использовать в качестве индекса в таблице из 99 предварительно вычисленных квадратных корней для завершения оценки.
    [math]a[/math]ближайший корень[math]\sqrt{a}[/math]
    от 1 до 2.51(=12)1
    от 2.5 до 6.54(=22)2
    от 6.5 до 12.59(=32)3
    от 12.5 до 20.516(=42)4
    от 20.5 до 30.525(=52)5
    от 30.5 до 42.5 36(=62)6
    от 42.5 до 56.549(=72)7
    от 56.5 до 72.564(=82)8
    от 72.5 до 90.581(=92)9
    от 90.5 до 100100(=102)10
    Для компьютера с основанием шестнадцать потребуется таблица большего размера, но для компьютера с основанием два потребуются только три записи: возможные биты целой части скорректированной мантиссы равны 01 (степень даже при отсутствии сдвига, помня, что нормализованная число с плавающей запятой всегда имеет ненулевую старшую цифру) или, если степень была нечетной, 10 или 11, это первые два бита исходной мантиссы. Таким образом, 6,25 = 110,01 в двоичном формате, нормализованное до 1,1001 × 22 четной степени, так что парные биты мантиссы равны 01, в то время как 0,625 = 0,101 в двоичной системе нормализуется до 1,01 × 2-1 нечетной степени, поэтому корректировка составляет 10,1 × 2-2, а парные биты равны 10. Обратите внимание, что бит младшего разряда мощности отражается эхом в бите старшего разряда попарной мантиссы. У четной мощности бит младшего разряда равен нулю, а скорректированная мантисса начинается с 0, тогда как для нечетной мощности этот бит равен единице, а скорректированная мантисса начинается с 1. Таким образом, когда число уменьшается вдвое, бит младшего разряда сдвигается, чтобы стать первым битом попарной мантиссы.
    Таблица только с тремя записями может быть увеличена за счет включения дополнительных бит мантиссы. Однако с компьютерами, чем вычислять интерполяцию в таблицу, часто лучше найти более простые вычисления, дающие эквивалентные результаты. Теперь все зависит от точных деталей формата представления, а также от того, какие операции доступны для доступа и управления частями числа. Например, Fortran предлагает функцию EXPONENT (x) для получения степени. Усилия, затраченные на разработку хорошего начального приближения, должны окупаться за счет исключения дополнительных итераций процесса уточнения, которые потребовались бы для плохого приближения. Поскольку их немного (одна итерация требует деления, сложения и деления пополам), ограничение является серьезным.
    Для компьютеров, использующих IEEE представление вещественного числа, методом Ньютона можно получить очень быстрое приближение к квадратному корню. Следующий алгоритм основан на том, что формат с вещественного числа по основанию два аппроксимируется логарифм по основанию 2. Это [math]\log _{2}(m\times 2^{p})=p+\log _{2}(m)[/math]

    Таким образом, для 32-разрядного числа с плавающей запятой одинарной точности в формате IEEE (где степень суммируется с числом 127), вы можете получить приблизительный логарифм, интерпретируя его двоичное представление как 32-битное целое число, масштабируя это от [math]2^{-23}[/math] и вычитание смещения 127, т. е. [math]x_{\text{int}}\cdot 2^{-23}-127\approx \log _{2}(x)[/math].
    Например, 1.0 в шестнадцатеричном виде 0x3F800000 будет представлять [math]1065353216=127\cdot 2^{23}[/math] если рассматривать как целое число. Используя формулу выше, вы получите [math]1065353216\cdot 2^{-23}-127=0[/math], как и ожидалось от [math]\log _{2}(1.0)[/math]. Аналогичным образом вы получаете 0,5 из 1,5 (0x3FC00000).

    Log2approx.png
    Чтобы получить квадратный корень, разделите логарифм на 2 и преобразуйте значение обратно. Следующая программа демонстрирует эту идею. Обратите внимание, что младшему разряду экспоненты намеренно разрешено распространяться в мантиссу. Один из способов обосновать шаги в этой программе - предположить, что [math]b[/math] - это смещение экспоненты, а [math]n[/math] - количество явно сохраненных бит в мантиссе, а затем показать, что
    [math](((x_{\text{int}}/2^{n}-b)/2)+b)\cdot 2^{n}=(x_{\text{int}}-2^{n})/2+((b+1)/2)\cdot 2^{n}[/math].
    Код (C):
    1. /* Assumes that float is in the IEEE 754 single precision floating point format */
    2. #include <stdint.h>
    3. float sqrt_approx(float z)
    4. {
    5.     union { float f; uint32_t i; } val = {z};    /* Convert type, preserving bit pattern */
    6.     /*
    7.      * To justify the following code, prove that
    8.      *
    9.      * ((((val.i / 2^m) - b) / 2) + b) * 2^m = ((val.i - 2^m) / 2) + ((b + 1) / 2) * 2^m)
    10.      *
    11.      * where
    12.      *
    13.      * b = exponent bias
    14.      * m = number of mantissa bits
    15.      */
    16.     val.i -= 1 << 23;    /* Subtract 2^m. */
    17.     val.i >>= 1;        /* Divide by 2. */
    18.     val.i += 1 << 29;    /* Add ((b + 1) / 2) * 2^m. */
    19.  
    20.     return val.f;        /* Interpret again as float */
    21. }
    Быстрый обратный квадратный корень
    Если x > 0.25, то ошибка меньше 0.6%
    Код (C):
    1. float  FastInvSqrt(float x)
    2. {
    3.     int tmp = ((0x3f800000 << 1) +
    4.            0x3f800000 - *(long*)&x) >> 1;
    5.     float y = *(float *)&tmp;
    6.     return y * (1.47f - 0.47f * x * y * y);
    7. }
    Алгоритм принимает 32-битное число с плавающей запятой (одинарной точности в формате IEEE 754) в качестве исходных данных и производит над ним следующие операции:
    1. Трактуя 32-битное дробное число как целое, провести операцию y0 = 0x5F3759DF − (x >> 1), где >> — битовый сдвиг вправо. Результат снова трактовать как 32-битное дробное число.
    2. Для уточнения можно провести одну итерацию метода Ньютона: y1 = y0(1,5 − 0,5x(y0)2).
    Корректная по меркам современного Си реализация, с учётом возможных оптимизаций и кроссплатформенности:
    Код (C):
    1. float Q_rsqrt( float number )
    2. {
    3.     const float x2 = number * 0.5F;
    4.     const float threehalfs = 1.5F;
    5.  
    6.     union {
    7.         float f;
    8.         uint32_t i;
    9.     } conv = {number}; // member 'f' set to value of 'number'.
    10.     conv.i = 0x5f3759df - ( conv.i >> 1 );
    11.     conv.f *= threehalfs - x2 * conv.f * conv.f;
    12.     return conv.f;
    13. }
     

    Вложения:

    • Converter8.zip
      Размер файла:
      207 КБ
      Просмотров:
      452
    Последнее редактирование: 3 ноя 2021
    rasstriga и Коцит нравится это.
  11. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Программа для перевода REAL10 в строку
    Код (ASM):
    1. $MagicLog2_32    equ 1292913987     ; = log(2) * 2^32
    2.     dp_1    equ 17      ; = decimal places minus 1
    3.     dp4     equ dp_1+4
    4. ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    5. ; Input:
    6. ;           esi = 10
    7. ;
    8. EXPONENTREAL_10KM MACRO
    9.                 cdq
    10.                 xor      eax,edx
    11. sub eax,edx            ; make number positive
    12.                 and dl,2
    13.                 add      byte ptr[edi+22],dl;if eax>=0 then "plus" else "minus"
    14.                 mov      edx,4294968        ;2^32/1000
    15.                 mul      edx                ;extend first digit
    16.                 shrd     ecx,edx,8          ;digit 1 in ECX
    17.                 mul      esi                ;extend second digit
    18.                 shrd     ecx,edx,8          ;digit 2 in ECX
    19.                 mul      esi                ;extend third digit
    20.                 shrd     ecx,edx,8          ;digit 3 in ECX
    21.                 mul      esi                ;extend fourth digit
    22.                 shrd     ecx,edx,8          ;digit 4 in ECX
    23.                 or       [edi+23],ecx       ;make ASCII string
    24. ENDM
    25. ;---------------------------------------------
    26. $maxexp     equ 90
    27. $maxcounter equ 2*$maxexp+1
    28. ;---------------------------------------------
    29. .data
    30. realexp4931    dt 1.0e+4931
    31.         shifttableX    dd shift0X    ; +0
    32.                         dd shift1X    ; +4
    33.                         dd shift2X    ; +8
    34.                         dd shift3X    ;+12
    35.                         dd shift4X    ;+16
    36. ;---------------------------------------------
    37.     cntr = -$maxexp
    38.     REPEAT $maxcounter
    39.         IF cntr NE 0
    40.             dt @CatStr(<1.0e>,%-cntr)
    41.         ELSE
    42.  PowerTable12  dt 1.0
    43.         ENDIF
    44.             dw 0
    45.         cntr = cntr + 1
    46.     ENDM
    47. ;----------------------------------------------------
    48. .code
    49. align 16
    50. Eprst         proc
    51. ; locals, buffer and args
    52. pReal10 equ dword ptr [esp+16+buffer]
    53. pStr equ pReal10+4
    54. iExp equ dword ptr [esp-4];0+4=4
    55. aExp equ iExp-4           ;4+4=8
    56. realx equ aExp-4*3         ;8+12=20
    57. temp equ realx-4*3        ;20+12=32
    58. buffer = 20h
    59.                         ;
    60.                           push    ebx
    61.                           push    esi
    62.                           push    edi
    63.                           sub   esp, buffer
    64.                           mov     ecx, pReal10                  
    65.                         ; ---------------------------
    66.                         ;        remove sign
    67.                         ;    move real10 to realx
    68.                         ; if iExp=0 we use this realx
    69.                         ; ---------------------------
    70.                   mov     edx, dword ptr [ecx+6]
    71.                   add   edx, edx; if CF=1 then negative
    72.                   mov     edi, pStr
    73.   sbb     eax, eax; if CF=0 then EAX = 0 else EAX = -1
    74.                           and   eax, 0Dh
    75.                           mov     aExp, 0
    76.                           or      eax, 2C0020h
    77.                           mov   [edi], eax; if CF=0 then EAX = 2C0020h else EAX = 2C002Dh
    78.                   shr   edx, 17 ; remove sign and if EDX = 0 go to _expzero
    79.                   mov     ebx, [ecx+0]
    80.                   mov     ecx, [ecx+4]
    81.                   mov     [realx+0], ebx
    82.                   mov     [realx+4], ecx
    83.                   mov     [realx+8], edx ; only exponent
    84.                   jz      _expzero ; if exponent = 0
    85.         _expnotzero:      cmp     edx, 7FFFh
    86.                   je      _isinfinity
    87.                         ;
    88.                           test    ecx, ecx
    89.                           jns     _erro1   ; if integer = 0 and exponent <> 0 then ERROR
    90.                           mov     ecx, pReal10
    91.                           fld   tbyte ptr [ecx]
    92.                           jmp     _begin
    93.                         ; ------------------------
    94.                         ;       exponent = 0
    95.                         ; ------------------------
    96. _expzero:                 or      ebx, ecx
    97.                           jz      _iszero       ; if edx = ebx = ecx = 0 is zero
    98.                           mov     ecx, pReal10
    99.                           fld   tbyte ptr [ecx]
    100.                         ;-------------------------
    101.                         ;    It is Denormal or
    102.                         ;     Pseudo-Denormal
    103.                         ;-------------------------
    104.                           fld     realexp4931     ; st(0)=1.0e+4931
    105.                   mov     aExp,-4931
    106.                   fmul                     ; normalization
    107.                   fld     st               ; get a copy
    108.                   fstp    tbyte ptr realx
    109.                         ;
    110.                   mov     ebx, [realx+0]
    111.                   and   [realx+8],7FFFh           ; remove sign
    112.                   mov     eax, [realx+4]
    113.                   mov     edx, [realx+8]
    114.                         ;---------------------
    115.                         ;       start
    116.                         ;---------------------
    117.                 _begin:   mov     esi, 10                            
    118.                         ;----------------------------------
    119.                         ; iExp= 4 * Exp because we multiply
    120.                         ;  by 2^16 and divide by 2^14 only
    121.                         ;----------------------------------
    122.   mov     eax, $MagicLog2_32   ; log(2)*2^32
    123.                   sub     edx, 3FFFh           ; =16383
    124.                   imul    edx
    125.                   mov     iExp, edx
    126.   or   edx,edx
    127.                           jz      short _getrealx ;edx = 0 ?
    128.                           cmp   edx, -1
    129.                           je      _new ;integer multipication to 10
    130.                   cmp     edx, $maxexp
    131.                   jg      @F
    132.                   cmp     edx,-$maxexp
    133.                   jge     short _load
    134. ;------------------------------------------------
    135.                  @@:      neg     edx
    136.                   fldl2t   ; log2(10)
    137.                   mov     [temp+8],edx
    138.                   fild    [temp+8]        ; x
    139.   mov     [temp+0],0
    140.                           fmul                    ; z = x * log2(10)
    141.   mov     [temp+4],3F000000h ; 0.5
    142.                           fld     st
    143.                           fsub    [temp+4]        ; z - 0.5
    144.                           fistp   [temp+8]        ; round(z)
    145.           mov     [temp+4],80000000h
    146.           fisub   [temp+8]        ;z - round(z)
    147.                           f2xm1                   ; 2^(mantissa)-1
    148.           add     [temp+8],3FFFh  ; 2^round(z)
    149.                           fld1
    150.                           fadd                    ; add 1 and pop
    151.                           fld     tbyte ptr temp
    152.                           fmul                    ; 2^((mantissa)*round(z))
    153.                           jmp     short @F        ;_multiply
    154. ;--------------------------------------------------------
    155.             _load:   shl     edx, 2                       ; edx = edx*4
    156.                           fld     [PowerTable12+edx+edx*2]    ; edx = edx*12
    157. ;--------------------------------------------------------
    158.                 @@:       fmul                    ; X * 10^expscaleS = d.??????
    159.                   fld      st              ; get a copy
    160.                   fstp     tbyte ptr realx
    161.                   xor      edx, edx
    162.                   mov      ebx, [realx+0]
    163. ;----------------------------------------------------------------
    164.         _getrealx:        mov      ecx, [realx+8]
    165.                           mov      eax, [realx+4]
    166.                         ;
    167.                   and      ecx, 7FFFh
    168.                   sub      ecx, 16382      ; 10=> exponent = 16386
    169.                   cmp      ecx, 4
    170.                   ja       shift0X
    171.                   jmp      [shifttableX+ecx*4]
    172. _new:                     mov      eax, ebx;[realx+0]
    173.                           add      eax,1
    174.                           mul      esi
    175.                           mov      ebx, eax
    176.                           mov      ecx, edx
    177.                           mov      eax, [realx+4]
    178.                           mul      esi
    179.                           add      eax, ecx
    180.                           jmp      _aa
    181.            shift4X::      test     eax, 60000000h              ; 6= 0110B
    182.                   jz       short a6
    183.                         ; ------------------------
    184.                         ; correct exponent * 10^-1
    185.                         ; exponent = exponent + 1
    186.                         ; ------------------------
    187.                   fld      [PowerTable12+12]          ; = 0.1
    188.                   fmul
    189.                   add      iExp, 1
    190.            ;       fld      st                  ; NEW get a copy
    191.                   fstp     tbyte ptr realx
    192.                   mov      eax, [realx+4]
    193.                           mov      ebx, [realx+0]
    194.                   jmp      shift1X
    195.                 a6:   shld     edx, eax, 4        ;ecx=1 ebx+4
    196.                   shld     eax, ebx, 4        ;ecx=2 ebx+8
    197.                   shl      ebx, 4             ;ecx=3 ebx+9
    198.                   add      ebx, 12;round       ;ecx=4 ebx+12
    199.                   jmp      shift0X
    200.                         ; -------------------------------
    201.                         ;    fraction bits in EAX:EBX
    202.                         ;    shift: EDX <- EAX <- EBX
    203.                         ; -------------------------------
    204.            shift3X::      shld     edx, eax, 3
    205.                   shld     eax, ebx, 3
    206.                   shl      ebx, 3              ; * 8
    207.                   add      ebx, 10 ;round
    208.                   jmp      shift0X
    209.                         ; -------------------------------
    210.                         ;    fraction bits in EAX:EBX
    211.                         ;    shift: EDX <- EAX <- EBX
    212.                         ; -------------------------------
    213.            shift2X::      shld     edx, eax, 2
    214.                   shld     eax, ebx, 2
    215.                   shl      ebx, 2              ; * 4
    216.                   add      ebx, 8              ;round
    217.                   jmp      shift0X
    218.                         ; -------------------------------
    219.                         ;    fraction bits in EAX:EBX
    220.                         ;    shift: EDX <- EAX <- EBX
    221.                         ; -------------------------------
    222.            shift1X::      shld     edx, eax, 1
    223.                   shld     eax, ebx, 1
    224.                   shl      ebx, 1              ; * 2
    225.                   add      ebx, 4              ;round
    226. ;-------------------------------------------------------
    227.                         ; -------------------------------
    228.                         ;  fraction bits in EDX:EAX:EBX
    229.                         ; -------------------------------
    230.            shift0X::      adc      eax, 0          ; add carry to eax and edx
    231.     _aa:          adc      edx, '0'        ; ASCII convert
    232.                         ;
    233.                           mov      dword ptr [edi+21],'00+E';ASCII chars for exponent
    234.   mov      dword ptr [edi+25],'00'
    235.                   mov      [edi+1], dl     ;first char in string
    236.                         ;------------------------------------------------
    237.                         ;                 eax          ebx
    238.                         ;                               10
    239.                         ;      ----------------------------
    240.                         ;                 ecx          ebx
    241.                         ;         edx     eax
    242.                         ;    ------------------------------
    243.                         ;   edx+carry     eax          ebx
    244.                         ;------------------------------------------------
    245.                     k=3
    246.                         REPEAT dp_1
    247.                             mov     ecx,eax         ; save EAX
    248.                             mov     eax,ebx
    249.                             mul     esi             ; edx:eax=ebx*10
    250.                             mov     ebx,eax
    251.                             mov     eax,ecx         ; restore EAX
    252.                             mov     ecx,edx         ; save EDX
    253.                             mul     esi             ; edx:eax=eax*10
    254.                             add     eax,ecx
    255.                             adc     edx,'0'         ; ASCII convert
    256.                             mov     [edi+k], dl     ; next char in string
    257.                     k=k+1
    258.                         ENDM
    259.                             mov     ecx,eax         ; save EAX
    260.                             mov     eax,ebx
    261.                             mul     esi             ; edx:eax=ebx*10
    262.                             mov     eax,ecx         ; restore EAX
    263.                             mov     ecx,edx         ; save EDX
    264.                             mul     esi             ; edx:eax=eax*10
    265.                             add     eax,ecx
    266.                             adc     edx,'0'         ; ASCII convert
    267.                     mov     eax, iExp
    268.                             mov     [edi+k], dl     ; last char in string
    269.                             add     eax, aExp
    270.                             jz      _exit ;if exponent=0 go to exit
    271.                         EXPONENTREAL_10KM
    272.             _exit:      mov edi,[esp+buffer] ;restore edi
    273.                         mov esi,[esp+buffer+4] ;restore esi
    274.                         mov ebx,[esp+buffer+8] ;restore ebx
    275.                         fstp     st(0)              ;remove realx
    276.                         add esp,buffer+12 ;remove buffer,locals
    277.                         xor      eax, eax               ;sucsess code
    278.                         retn 8 ;go to main program
    279. ;-----------------------------------------------------------
    280.     _isinfinity:        test      ecx,ecx
    281.                         jns      short _erro1               ; is NAN
    282.                         cmp      ecx,80000000h
    283.                         jnz      _other
    284.                         or       ebx, ebx
    285.                         jne      short _erro1               ; is NAN
    286.                         mov      dword ptr [edi+1], "IFNI"
    287.                         mov      dword ptr [edi+5], "YTIN"
    288.                         mov      dword ptr [edi+9],0
    289.                         xor      eax, eax
    290.                         mov edi,[esp+buffer];pop      edi
    291.                         mov esi,[esp+buffer+4];pop      esi
    292.                         mov ebx,[esp+buffer+8];pop      ebx
    293.                         add esp,buffer+12
    294.                         ret 8
    295.                         ;--------------------------
    296.                         ; value to be converted = 0
    297.                         ;--------------------------
    298.         _iszero:        mov esi,[esp+buffer+4];pop      esi
    299.                         mov      dword ptr [edi+1],"0.0"
    300.                         mov ebx,[esp+buffer+8];pop      ebx
    301.                         mov edi,[esp+buffer];pop      edi
    302.                         add esp,buffer+12
    303.                         xor      eax, eax
    304.                         ret 8
    305.                         ; --------------------
    306.                         ; is indefinite or NAN
    307.                         ; --------------------
    308.         _erro1:         mov      eax, 1
    309.                         mov      dword ptr [edi+1], "ORRE"
    310.                         mov      dword ptr [edi+5], "R"
    311.                         stc
    312.                         mov edi,[esp+buffer];pop      edi
    313.                         mov esi,[esp+buffer+4];pop      esi
    314.                         mov ebx,[esp+buffer+8];pop      ebx
    315.                         add esp,buffer+12
    316.                         ret 8
    317.         _other:         test    ecx,0BFFFFFFFh
    318.                         jnz     _other1
    319.                         mov      dword ptr [edi+1], "ngiS"
    320.                         mov      dword ptr [edi+5], "nila"
    321.                         mov      dword ptr [edi+9], "aN g"
    322.                         mov      dword ptr [edi+13],"N"
    323.                         xor      eax, eax
    324.                         mov edi,[esp+buffer];pop      edi
    325.                         mov esi,[esp+buffer+4];pop      esi
    326.                         mov ebx,[esp+buffer+8];pop      ebx
    327.                         add esp,buffer+12
    328.                         ret 8
    329. _other1:        cmp      ecx,0C0000000h
    330.                         jnz     _Quit_NaN
    331.                         or       ebx, ebx
    332.                         jne     _Quit_NaN
    333.                         mov      dword ptr [edi+1], "ednI"
    334.                         mov      dword ptr [edi+5], "inif"
    335.                         mov      dword ptr [edi+9], "et"
    336.                         xor      eax, eax
    337.                         mov edi,[esp+buffer];pop      edi
    338.                         mov esi,[esp+buffer+4];pop      esi
    339.                         mov ebx,[esp+buffer+8];pop      ebx
    340.                         add esp,buffer+12
    341.                         ret 8
    342.       _Quit_NaN:        mov      dword ptr [edi+1], "eiuQ"
    343.                         mov      dword ptr [edi+5], "aN t"
    344.                         mov      dword ptr [edi+9], "N"
    345.                         xor      eax, eax
    346.                         mov edi,[esp+buffer];pop      edi
    347.                         mov esi,[esp+buffer+4];pop      esi
    348.                         mov ebx,[esp+buffer+8];pop      ebx
    349.                         add esp,buffer+12
    350.                         ret 8
    351. Eprst         endp
    Программа для перевода REAL4 в строку
    Программа для перевода REAL8 в строку

    integer to float32


    Код (ASM):
    1. .data
    2. x dw 1ABCh
    3. y dd 0
    4. .code
    5.         mov ax,[x]
    6.         or ax,ax
    7.         jz exit
    8.         jns @f
    9.         mov byte ptr [y+3],80h
    10.         neg ax
    11. @@:     mov cl,16
    12.         bsr bx,ax
    13.         sub cl,bl
    14.         shl ax,cl
    15.         shr ax,1
    16.         add bx,127
    17.         shl bx,7
    18.         or word ptr [y+2],bx
    19.         or word ptr [y+1],ax
    20. exit:

    integer to float64

    Код (ASM):
    1. .data
    2. x dw -7935
    3. y dq 0
    4. .code
    5.         mov ax,[x]
    6.         or ax,ax
    7.         jz exit
    8.         jns @f
    9.         mov byte ptr [y+7],80h
    10.         neg ax
    11. @@:     mov cl,16
    12.         bsr bx,ax
    13.         sub cl,bl
    14.         shl ax,cl
    15.         add bx,1023
    16.         shld bx,ax,4
    17.         shl ax,4
    18.         or word ptr [y+6],bx
    19.         mov word ptr [y+4],ax
    20. exit:

    integer to float80

    Код (ASM):
    1. .data
    2. x dw 1EFFh
    3. y dt 0
    4. .code
    5.         mov ax,[x]
    6.         or ax,ax
    7.         jz exit
    8.         jns @f
    9.         mov byte ptr [y+9],80h
    10.         neg ax
    11. @@:     mov cl,15
    12.         bsr bx,ax
    13.         sub cl,bl
    14.         shl ax,cl
    15.         add bx,16383
    16.         or word ptr [y+8],bx
    17.         mov word ptr [y+6],ax
    18. exit:

    Использованы материалы:


    1. Чарльз Петцольд «Код. Тайный язык информатики» — М.: Издательско-торговый дом «Русская Редакция», 2001. — 512 с.: ил.
    2. Serrgio / HI-TECH «Введение в машинный код» (Архив WASM.RU)
    3. Кнут, Дональд Эрвин «Искусство программирования. Том 2: Получисленные алгоритмы», 3-е изд.: — М.: Издательско-торговый дом «Вильямс», 2003. — 832 с.: ил.
    4. Сергей Борисович Гашков «Системы счисления и их применение» Серия: «Математическое просвещение» Выпуск 29. М.: МЦНМО, 2004. — 52 с.: ил.
    5. Материалы с сайта http://klein.zen.ru/klein/hscool/online/base/b1s1/
     

    Вложения:

    • Mikl_4.zip
      Размер файла:
      33,3 КБ
      Просмотров:
      323
    • ConverterDF.zip
      Размер файла:
      40,8 КБ
      Просмотров:
      570