Неверов Евгений Викторович
QR-код
Меню сайта
Категории раздела
Программирование на языке Паскаль [26]
В данной категории представлены новые функции, созданные на языке Паскаль, которые могут пригодиться при написании своих программ
Программирование на Delphi [19]
В данной категории представлены полезные подпрограммы, которые могут пригодиться при написании своих программ, а также рассматриваются примеры готовых проектов, создаваемых в среде программирования Delphi
Программирование на HTML [1]
В данной категории рассматриваются примеры готовых проектов, создаваемых на языке HTML
Мои программы [1]
Описание разработанных автором программ.
Online-программы [2]
Прочее [42]
Свободная тематика
Мини-чат
200
Наш опрос
Оцените мой сайт
Всего ответов: 59
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Перевод чисел из одних систем счисления в другие

1. Определение кода числа системы счисления

Сначала создадим вспомогательную функцию SystemNumChar, необходимая для нашей работы. Она конвертирует цифру в букву латинского алфавита. Например, цифра '11' – это 'B'; '15' – это F'; '7' – это '7' (цифры от 0 до 9 остаются без изменений).

function SystemNumChar(n: byte): char;
begin
   Result:='0';
   if n<=9 then
      Result:=Char(48+n);
   if (n>=10) and (n<=35) then
      Result:=Char(55+n);
end;

где:

  • n – цифра от 0 до 35.

Например,

  • SystemNumChar(2) выведет '2';
  • SystemNumChar(14) выведет 'E' (как в шестнадцатеричной системе счисления);
  • SystemNumChar(33) выведет 'X'.

Примечание. В настоящее время существуют 16-ричные системы счисления, однако автор решил пофантазировать и расширил весь латинский алфавит. Поэтому не стоит удивляться, если при вызове функции SystemNumChar(35) выведет 'Z'. Но может в дальнейшем "изобретут" 32-ричные системы счисления, 36-ричные и т.д.


Также создадим вспомогательную функцию SystemNumByte, обратная функции SystemNumChar.

function SystemNumByte(c: char): byte;
begin
   Result:=0;
   c:=UpCase(c);
   if (c>='0') and (c<='9') then
      Result:=Ord(c)-48;
   if (c>='A') and (c<='Z') then
      Result:=Ord(c)-55;
end;

где:

  • c – буква от 0 до 9, от A до Z.

Например,

  • SystemNumByte('7') выведет '7';
  • SystemNumByte('F') выведет '15';
  • SystemNumByte('z') выведет '35' (не зависит от регистра букв).

Перевод целых положительных чисел из одной системы счисления в другую

2. Перевод чисел из десятичной системы счисления в двоичную (частный случай)

1 вариант:

function SystemNum10to2(n: int64): string;
var i: byte;
begin
   Result:='';
   while n>0 do
   begin
      i:=n mod 2;
      Result:=IntToStr(i)+Result;
      n:=n div 2;
   end;
   if Result='' then
      Result:='0';
end;

2 вариант:

function SystemNum10to2(n: int64): string;
var i: byte;
begin
   Result:='';
   while n>0 do
   begin
      i:=n and 1;
      Result:=IntToStr(i)+Result;
      n:=n shr 1;
   end;
   if Result='' then
      Result:='0';
end;

где:

  • n – исходное десятичное число.

Например,

  • SystemNum10to2(12) выведет '1100';
  • SystemNum10to2(45) выведет '101101'.

3. Перевод чисел из десятичной системы счисления в шестнадцатеричную (частный случай)

function SystemNum10to16(n: int64): string;
var i: byte;
begin
   Result:='';
   while n>0 do
   begin
      i:=n mod 16;
      Result:=SystemNumChar(i)+Result;
      n:=n div 16;
   end;
   if Result='' then
      Result:='0';
end;

где:

  • n – исходное десятичное число.

Например,

  • SystemNum10to16(24) выведет '18';
  • SystemNum10to16(16383) выведет '3FFF'.

4. Перевод чисел из десятичной системы счисления в любую другую

function SystemNum10toB(n: int64; b: byte): string;
var i: byte;
begin
   Result:='';
   if (b<2) or (b>36) then
      Exit;
   while n>0 do
   begin
      i:=n mod b;
      Result:=SystemNumChar(i)+Result;
      n:=n div b;
   end;
   if Result='' then
      Result:='0';
end;

где:

  • n – исходное десятичное число;
  • b – система счисления.

Например,

  • SystemNum10toB(225, 2) выведет '11100001';
  • SystemNum10toB(173, 5) выведет '1143';
  • SystemNum10toB(541, 16) выведет '21D';
  • самое интересное, что SystemNum10toB(1583, 36) выведет '17Z'.

5. Перевод чисел из двоичной системы счисления в десятичную (частный случай)

function SystemNum2to10(s: string): int64;
var i, k: byte;
    step: int64;
begin
   Result:=0;
   step:=1;
   for i:=Length(s) downto 1 do
   begin
      if (s[i]<'0') or (s[i]>'1') then
      begin
         { защита от посторонних символов }
         Result:=0;
         Exit;
      end;
      k:=StrToInt(s[i]);
      Result:=Result+k*step;
      step:=step*2;
   end;
end;

где:

  • s – исходное двоичное число.

Например,

  • SystemNum2to10('1110') выведет '14'.

6. Перевод чисел из шестнадцатеричной системы счисления в десятичную (частный случай)

function SystemNum16to10(s: string): int64;
var i, k: byte;
    step: int64;
begin
   Result:=0;
   step:=1;
   for i:=Length(s) downto 1 do
   begin
      k:=SystemNumByte(s[i]);
      Result:=Result+k*step;
      step:=step*16;
   end;
end;

где:

  • s – исходное шестнадцатеричное число.

Например,

  • SystemNum16to10('E40A') выведет '58378'.

7. Перевод чисел из любой системы счисления в десятичную

function SystemNumAto10(s: string; a: byte): int64;
var i, k: byte;
    step: int64;
begin
   Result:=0;
   if (a<2) or (a>36) then
      Exit;
   step:=1;
   for i:=Length(s) downto 1 do
   begin
      k:=SystemNumByte(s[i]);
      Result:=Result+k*step;
      step:=step*a;
   end;
end;

где:

  • s – исходное число любой системы счисления, записанное в строковом виде;
  • a – система счисления.

Например,

  • SystemNumAto10('11001', 2) выведет '25';
  • SystemNumAto10('8137', 9) выведет '5947';
  • SystemNumAto10('6a7D', 16) выведет '27261' (не зависит от регистра букв);
  • SystemNumAto10('53z', 36) выведет '6623'.

8. Перевод чисел из двоичной системы счисления в шестнадцатеричную (частный случай)

function SystemNum2to16(s: string): string;
const Base: array[0..15, 0..1] of string =
        (('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'));
var i, j: byte;
begin
   Result:='';
   while Length(s) mod 4<>0 do
      s:='0'+s;
   for i:=1 to Length(s) div 4 do
      for j:=Low(Base) to High(Base) do
         if Base[j, 0]=Copy(s, 4*i-3, 4) then
         begin
            Result:=Result+Base[j, 1];
            Break;
         end;
   if Result='' then
      Result:='0';
end;

где:

  • s – исходное двоичное число.

Например,

  • SystemNum2to16('101101') выведет '2D';
  • SystemNum2to16('111000110') выведет '1C6'.

9. Перевод чисел из шестнадцатеричной системы счисления в двоичную (частный случай)

function SystemNum16to2(s: string): string;
const Base: array[0..15, 0..1] of string =
        (('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'));
var i, j: byte;
begin
   Result:='';
   for i:=1 to Length(s) do
      for j:=Low(Base) to High(Base) do
         if Base[j, 1]=UpCase(s[i]) then
         begin
            Result:=Result+Base[j, 0];
            Break;
         end;
   while (Result<>'') and (Result[1]='0') do
      Delete(Result, 1, 1);
   if Result='' then
      Result:='0';
end;

где:

  • s – исходное шестнадцатеричное число.

Например,

  • SystemNum16to2('3a') выведет '111010'.

10. Перевод чисел из любой системы счисления в любую другую (общий случай)

1 вариант:

function SystemNumAtoB(s: string; a, b: byte): string;
var i, k: byte;
    n, step: int64;
begin
   Result:='';
   if (a<2) or (a>36) or (b<2) or (b>36) then
      Exit;
   { перевод в десятичное число }
   n:=0;
   step:=1;
   for i:=Length(s) downto 1 do
   begin
      k:=SystemNumByte(s[i]);
      n:=n+k*step;
      step:=step*a;
   end;
   { далее перевод в нужную систему счисления }
   while n>0 do
   begin
      i:=n mod b;
      Result:=SystemNumChar(i)+Result;
      n:=n div b;
   end;
   if Result='' then
      Result:='0';
end;

2 вариант:

function SystemNumAtoB(s: string; a, b: byte): string;
var n: int64;
begin
   n:=SystemNumAto10(s, a);
   Result:=SystemNum10toB(n, b);
end;

где:

  • s – исходное число любой системы счисления, записанное в строковом виде;
  • a – система счисления числа s;
  • b – система счисления получаемого числа.

Например,

  • SystemNumAtoB('11110', 2, 10) выведет '30';
  • SystemNumAtoB('2B', 16, 10) выведет '43';
  • SystemNumAtoB('114', 8, 16) выведет '4C';
  • SystemNumAtoB('z', 36, 2) выведет '100011';
  • SystemNumAtoB('B93', 12, 25) выведет '2HK'.

Перевод вещественных положительных чисел из одной системы счисления в другую

Под вещественными числами в программировании понимаются дробные десятичные числа.

11. Перевод вещественных чисел из десятичной системы счисления в любую другую

function SystemNumR10toB(n: real; b, c: byte): string;
var i: byte;
begin
   Result:=SystemNum10toB(Trunc(n), b);
   if c>0 then
      Result:=Result+',';
   for i:=1 to c do
   begin
      n:=Frac(n)*b;
      Result:=Result+SystemNumChar(Trunc(n));
   end;
end;

где:

  • n – исходное вещественное десятичное число;
  • b – система счисления;
  • c – количество цифр после запятой.

Например,

  • SystemNumR10toB(9.875, 2, 5) выведет '1001,11100';
  • SystemNumR10toB(25.93, 6, 10) выведет '41,5325140251';
  • SystemNumR10toB(0.01, 16, 7) выведет '0,028F5C2'.

12. Перевод вещественных чисел из любой системы счисления в десятичную

function SystemNumRAto10(s: string; a: byte): real;
var i, k: byte;
    step: int64;
    sk { дробная часть числа }: string;
begin
   Result:=0;
   if (a<2) or (a>36) then
      Exit;
   k:=Pos(',', s);
   if k>0 then
   begin
      sk:=Copy(s, k+1, Length(s));
      s:=Copy(s, 1, k-1);
   end else
      sk:='';
   Result:=SystemNumAto10(s, a);
   step:=a;
   for i:=1 to Length(sk) do
   begin
      k:=SystemNumByte(sk[i]);
      Result:=Result+k/step;
      step:=step*a;
   end;
end;

где:

  • s – исходное вещественное число любой системы счисления, записанное в строковом виде;
  • a – система счисления.

Например,

  • SystemNumRAto10('11,0001', 2) выведет '3,0625';
  • SystemNumRAto10('62,017', 7) выведет '44,0408163265306';
  • SystemNumRAto10('A,3D', 16) выведет '10,23828125'.

Перевод целых отрицательных чисел из одной системы счисления в другую

Существуют ограничения на числа, которые могут быть записаны в n-разрядную ячейку памяти. При знаковом представлении целых чисел старший разряд ячейки отводится под знак (0 – для положительных, 1 – для отрицательных чисел), а остальные разряды – под цифры числа. Возьмем, например, число '147', двоичная запись которого – '10010011'. Также возьмем число '-109', двоичная запись которого – '10010011'. Мы видим, что двоичные коды чисел '147' и '-109' совпадают. Если для числа '147' потребуется 2 байта памяти (16-разрядная ячейка памяти), то для числа '-109' хватит 1 байта (8-разрядная ячейка). Поэтому при переводе отрицательных чисел нужно указывать количество разрядов. Следовательно, вышеуказанные функции для перевода отрицательных чисел точно не подойдут!

13. Перевод отрицательных чисел из десятичной системы счисления в любую другую

function SystemNumN10toB(n: int64; b: byte): string;
var i, k, z, len: byte;
    min, max: int64;
    minus: boolean;

   procedure BitCount(byt { байты }: byte);
   var a, b: int64;
       bit { биты }: byte;
   begin
      bit:=8*byt-1;
      a:=-(int64(1) shl bit); // -128
      b:=int64(1) shl bit - 1; // 127
      if (a<=n) and (n<=b) then
      begin
         min:=a;
         max:=b;
         z:=byt; // 1 (байт)
      end;
   end;

begin
   Result:='';
   if (b<2) or (b>36) then
      Exit;
   { определяем диапазон допустимых чисел, например, от -128 до 127 (1 байт) }
   min:=0;
   max:=0;
   z:=0;
   BitCount(8);
   BitCount(4);
   BitCount(2);
   BitCount(1);
   { определяем длину выводимой строки результата }
   case b of
   2: len:=8*z;
   3: len:=5*z;
   4..6: len:=4*z;
   7..15: len:=3*z;
   else
      len:=2*z;
   end;
   { процесс вычисления }
   minus:=n<0;
   n:=Abs(n);
   z:=1;
   for k:=1 to len do
   begin
      i:=n mod b;
      if minus then
      begin
         i:=b-i+z-1;
         z:=i div b;
         i:=i mod b;
      end;
      Result:=SystemNumChar(i)+Result;
      n:=n div b;
   end;
end;

где:

  • n – исходное десятичное число;
  • b – система счисления.

Например,

  • SystemNumN10toB(-128, 2) выведет '10000000';
  • SystemNumN10toB(-255, 6) выведет '55554453';
  • SystemNumN10toB(-1024, 16) выведет 'FC00';
  • SystemNumN10toB(1024, 16) выведет '0400'.

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


14. Перевод отрицательных чисел из любой системы счисления в десятичную

function SystemNumNAto10(s: string; a: byte): int64;
var i, k, len: byte;
    max, step: int64;
begin
   Result:=0;
   if (a<2) or (a>36) then
      Exit;
   case a of
   2: len:=8;
   3: len:=5;
   4..6: len:=4;
   7..15: len:=3;
   else
      len:=2;
   end;
   k:=Length(s) div len;
   len:=Length(s) mod len;
   if len>0 then
      k:=k+len; // 1 (байт)
   k:=8*k-1; // 7 (бит)
   max:=int64(1) shl k - 1; // 127
   Result:=SystemNumAto10(s, a);
   if Result>max then
   begin
      Result:=0;
      step:=1;
      for i:=Length(s) downto 1 do
      begin
         k:=SystemNumByte(s[i]);
         k:=a-k-1;
         Result:=Result+k*step;
         step:=step*a;
      end;
      Result:=-Result-1;
   end;
end;

где:

  • s – исходное число любой системы счисления, записанное в строковом виде;
  • a – система счисления.

Например,

  • SystemNumNAto10('11110110', 2) выведет '-10';
  • SystemNumNAto10('8000', 16) выведет '-32768'.

Примечание. Важное для всех функций! Если в некоторых версиях языка Паскаль целочисленных тип int64 отсутствует, то его можно заменить на integer. Правда диапазон чисел уменьшится на 4 байта.

Категория: Программирование на языке Паскаль | Добавил: newerow1989 (12.03.2016)
Просмотров: 1782 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email:
Код *:
Вход на сайт
Поиск
Друзья сайта
Заработок в Интернете
Для начала необходим Электронный PAYEER® кошелек!
Copyright MyCorp © 2025
Версия для мобильных устройств. Яндекс.Метрика Анализ сайта Проверить мой сайт на ScamAdviser.com