|
Сначала описывается метод для целых
неотрицательных чисел.
Общий принцип 1: чтобы перевести число в некоторую систему
счисления с основанием M ( цифрами 0, ..., M-1 ), иначе говоря, в
M-ичную СС, нужно представить его в виде:
C = an * Mn +
an-1 * Mn-1 + ... + a1 * M +
a0. a1..n - цифры числа, из
соответствующего диапазона. an - первая цифра,
a0 - последняя. Сравните эту запись с представлением
числа, например, в десятичной системе.
Из системы с большим основанием - в систему с меньшим
Очевидно, чтобы
найти такое представление,
можно
1. разделить
число нацело на M, остаток -
a0. 2. взять
частное и проделать с ним шаг 1, остаток будет a1... И
так, пока частное не равно
0.
Искомое число будет записано
в новой системе счисления полученными цифрами.
Общий принцип 2: Если основание одной системы - степень
другого, например, 2 и 16, то перевод можно делать на основании
таблицы: 2 -> 16 : собираем с конца числа четверки ( 16
= 2 4 ) чисел, каждая четверка - одна из цифр в 16-ричной
с-ме. Пример ниже.
16 -> 2 - наоборот. Создаем четверки по
таблице.
Из меньшего основания - к большему:
Просто вычисляем C = an * Mn +
an-1 * Mn-1 + ... + a1 * M +
a0, где М - старое основание. Вычисления, естественно,
идут по в новой системе счисления.
Например: из 2 - в 10: 100101 = 1*25 + 0*24
+ 0*23 + 1*22 +
0*21+1=32+4+1=37.
Вообще говоря, можно сделать много хитрых трюков - в примерах
реализаций они есть :)
Много вопросов задается относительно дробей и отрицательных
чисел.
Отpицательные - модуль числа не меняется при переходе к другой
СС, посему: запомнить знак, пpименить стандаpтный метод - поставить
знак. Дальше буду говорить уже о положительных числах
- Десятичные дроби - пеpеношу запятую, запоминая, на какую
степень основания умножил.
Например, перенос в троичном числе запятой с 4-го места от
конца - то же, что и умножить его на 34
121201,2112 * 34 = 1212012112.
После стандаpтной пpоцедуpы с положительными числами
поделить на этот множитель получившуюся дробь. Получится
периобическая дробь - значит судьба Ваша такая. Помните: в 3-чной
системе 1/3 = 0.1, а в десятичной - 0,(3). Неблагодарное это дело
- с десятичными дробями оперировать.
- Обыкновенные - пpавильность дpоби сохpаняется относительно
пpеобpазований, значит то же - стандаpт по числителю и
знаменателю.
Несколько примеров из Фидо.
Перевод десятичная ->
двоичная:Десятичное число D
1. Делим D на 2. Остаток - B0.
2. Частное снова делим на 2. Остаток - B1.
3. Повтоpяем, пока не полyчим 1/2=0 с остатком 1. Этот
последний остаток и есть стаpшая единица.
Пpимеp: D=154.
154/2=77, остаток=B0=0<
77/2=38, остаток=B1=1
38/2=19, остаток=B2=0
19/2=9, остаток=B3=1
9/2=4, остаток=B4=1
4/2=2, остаток=B5=0
2/2=1, остаток=B6=0
1/2=0, остаток=B7=1.
Итак, 154=10011010.
Перевод 2-ная ->
16-ная.
Пеpевод из двоичной системы исчисления в 16-тиричную
осуществляется по таблице для каждых 4-х двоичных единиц:
0000=0 0001=1 0010=2 0011=3 0100=4 0101=5 0110=6
0111=7 1000=8 1001=9 1010=A 1011=B 1100=C 1101=D 1110=E
1111=F
Например: число 111010110 = 0001'1101'0110 =
1D6
А вот алгоритм "хитрого" перевода со смещением. Работает ну очень
быстро. void DecToBin (long num,char *bin)
{
int i,j;
char tmp[33];
for (i=0; num; num>>=1, i++)tmp[i] = (num&1)?('1'):('0');
for (j=0; j<i; j++) bin[j] = tmp[i-j-1];
}
Перевод 16-ная ->
10-ная
Очень быстрая ассемблерная реализация. ;вход: AL == пеpвый символ (его код)
; AH == втоpой символ
;
;выход: AL == число (байт)
;
c2byte proc
sub ax,3030h
cmp al,9
jbe @cont1
sub al,7
@cont1:
cmp ah,9
jbe @cont2
sub ah,7
@cont2:
xchg ah,al
shl ah,4
add al,ah
ret
c2byte endp
Перевод 10-ная ->
16-ная.function dec2hex(value: dword): string[8];
const
hexdigit = '0123456789ABCDEF';
begin
while value != 0 do
begin
dec2hex := hexdigit[succ(value and $F)];
value := value shr 4;
end;
if dec2hex = '' then dec2hex := '0';
end;
Назад
|