| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Asm для начинающих > Перевод ЧПЗ, ЧФЗ |
| Автор: n199a 27.12.2013, 00:06 |
| ЧФЗ - число с фиксированной запятой. ЧПЗ - число с плавающей запятой.
Искал, читал, непонятно Как я понимаю: 125,25(10) = 011 1101, 000 0100 (2) Получается, что, полученное число в двоичном формате уже есть ЧФЗ (число с фиксированной запятой) ? |
| Автор: tzirechnoy 31.12.2013, 10:22 | ||
Нет, 125(10) = 1111101(2), а 0.25(10) = 0.01(2) Вообще, традицыонный алгоритм перевода цэлого числа в p-ичную систему -- это делить с остатком на p, остатки последовательно справа налево записываются в разряды p-ичного числа, результат делится опять пока не получится 0. Перевод дробной части в p-ичную систему -- это умножать на p, цэлую часть получившэгося числа записывать в следующий слева направа после десятичной точки разряд p-ичного числа, дробную часть брать и опять умножать на p. Продолжать либо пока не получится 0, либо пока не получится число, которое ужэ было -- тогда запись периодическая, цыфры от предыдущей такой жэ дробной части до предыдущей полученной цыфры бесконечно повторяются. Если число так или иначе ограниченного размера -- то перевод дробной части делается пока не упрёмся в ограничения размера числа. Например, 125_(10) ÷ 2 = 62 ост 1 1_(2) 62_(10) ÷ 2 = 31 ост 0 01_(2) 31_(10) ÷ 2 = 15 ост 1 101_(2) 15_(10) ÷ 2 = 7 ост 1 1101_(2) 7_(10) ÷ 2 = 3 ост 1 11101_(2) 3_(10) ÷ 2 = 1 ост 1 111101_(2) 1_(10) ÷ 2 = 0 ост 1 1111101_(2) -- это результат перевода. 0.25_(10) × 2 = 0.5, целая часть -- 0 0.0_(2) 0.5_(10) × 2 - 1, целая часть -- 1 0.01_(2) дробная часть 0, так что останавливаемся. Результат: 125.25_(10)=1111101.01_(2) Пример дроби, которая в системе исчисления 2 будет бесконечной периодической: 0.3_(10) × 2 = 0.6, [0.6]=9 0.0_(2) 0.6_(10) × 2 = 1.2, [1.2]=1 0.01_(2) 0.2_(10) × 2 = 0.4, [0.4]=0 0.010_(2) 0.4_(10) × 2 = 0.8, [0.8]=0 0.0100_(2) 0.8_(10) × 2 = 1.6, [1.6]=1 0.01001_(2) 0.6 -- ужэ было, всё остальное будет повтором цыфр со второго шага: 0.3_(10) = 0.01001100110011001... = 0.0(1001)_(2) Далее про фиксированную и плавающую точку: числа с фиксированной точкой -- так и записываются, сколько-то цыфр (в двоичной системе -- бит) до точки, сколько-то после. Кстати, поэтому можно прерывать вычисление дробной части после определённого количества шагов: сколько цыфр надо -- столько получил, остальное ненужно. У чисел с плавающей точкой всё веселее: они записываются в виде дробного числа 0.xxxxxx, умножэнного на 2^n (это значок возведения в степень). Т.е. 1111101.01 будет 0.111110101_(2) * 2^7 = 0.111110101_(2) * 2^111_(2). Соответственно, в памяти компьютэра выделяется сколько-то бит на хранения мантиссы (вот этого 0.111110101, обычно при этом первая 1 -- не записывается, а подразумевается), и сколько-то на хренение характеристики (вот этого 111). И характеристика и мантисса, кстати, могут быть отрицательными -- т.е. на знак у них тожэ около одного бита выделяется. Перевод внутри двоичной системы из фиксированной точки в плавающую -- довольно очевиден, сдвинуть значение на нужное число разрядов, чтобы получилось 0.1xxxx (т.е. чтобы цэлой части не было, а первая цыфра после точки была значащей), сдвиг записать в характеристику с обратным по отношэнию к обычному умножэнию на 2^n знаком -- т.е. если сдвигали вправо, то со знаком плюс. Напомню, кстати, что умножэние на 2^n в двоичной системе производится сдвигом цыфр -- ну, такжэ как в десятичной умножэние на 10^n (12*10^3 = 12000, 12/10^3 = 0.012). Около одного бита на знак, кстати -- это поскольку варианты хранения чисел со знаком могут быть разными, например, мне где-то встречался такой: характеристика хранится в виде положытельного цэлого, от 0 до 32767 -- а чтобы получить реальную характеристику -- из него вычитается 8192. Таким образом, доступны характеристики от -8192 до 24575 -- что бывает удобно, поскольку астрономически-большые числа нужны чаще. Как-то так. |