Как написать программу для перевода в другую систему счисления

В прошлом году я писал программу для перевода из любой системы в любую систему счисления на си. Теперь потребовалось на Pascal.Функций стало больше. Некоторые пришлось просто копировать с других сайтов (да простят меня авторы)

К сожалению, точность вычислений здесь меньше, чем была на си — всего один знак после запятой точен.

Ограничение во FreePascal: числа в 16-ричной системе можно вводить только большими буквами. Нет функции UpperCase, писать было лень 🙂
Исходный код (FreePascal):

program test; uses crt, math, strings; var s, s1,s2 : string; // число для перевода base_in : integer; // Основание входной системы счисления base_out : integer; // Основание выходной системы счисления function CheckDotCount(s: string): boolean; // Проверка количества точек в числе var count, i : integer; begin count := 0; for i := 1 to Length(s) do if (s[i] = ‘.’) then inc(count); if (count > 1) then CheckDotCount := false else CheckDotCount := true; end; function IntToHex(ds: byte): string; const b: string = ‘0123456789ABCDEF’; begin if (b[(ds shr 4) + 1] = ‘0’) then IntToHex:= b[(ds and $F) + 1] else IntToHex:= b[(ds shr 4) + 1] + b[(ds and $F) + 1]; end; function HexToInt(s: string): Longword; var b: Byte; c: Char; r: Longword; begin r := 0; //s := UpperCase(s); for b := 1 to Length(s) do begin r := r * 16; c := s[b]; case c of ‘0’..’9′: Inc(r, Ord(c) — Ord(‘0’)); ‘A’..’F’: Inc(r, Ord(c) — Ord(‘A’) + 10); end; end; HexToInt := r; end; function checkSS(base : integer; s : string): boolean; var i: integer; flag : boolean; begin flag := true; for i := 1 to Length(s) do begin if (HexToInt(s[i]) >= base) then flag := false; end; if ((base > 16) or (base < 2)) then flag := false; checkSS := flag; end; function checkSSR (base : integer):boolean; begin if ((base >16) or (base < 2)) then checkSSR := false else checkSSR := true; end; function getStringBeforeDot(s:string): string; //pos : integer; begin if (Pos(‘.’,s) = 0) then getStringBeforeDot := s else getStringBeforeDot := Copy(s, 1,Pos(‘.’,s)-1); end; function getStringAfterDot(s: string):string; begin if (Pos(‘.’,s) = 0) then getStringAfterDot := » else getStringAfterDot := copy(s,Pos(‘.’,s)+1,Length(s)); end; procedure IntConverter(s:string; base_in : integer; base_out : integer); var n1,N,i,r1 : integer; d1 : array [0..255] of integer; begin n1 := Length(s); N := 0; for i := 1 to n1 do begin N:= N*base_in+HexToInt(s[i]); end; if (N = 0) then write (‘0’) else begin r1 := 0; while (N <>0) do begin d1[r1] := N mod base_out; N := N div base_out; inc(r1); end; for i:=r1-1 downto 0 do write(IntToHex(d1[i])); end; end; procedure DotConverter(s:string; base_in : integer; base_out : integer); var n2 , i, k2: longint; Nf : double; begin n2 := Length(s); if (n2 = 0) then begin writeln(); exit; end; write(‘.’); Nf := 0; for i := n2 downto 1 do begin Nf := (HexToInt(s[i]) + Nf) / base_in; end; k2 := 0; while ((Nf <> 0) AND (k2 < 5)) do begin inc(k2); write(IntToHex(floor(Nf*base_out))); Nf := ((Nf*base_out)); end; end; begin writeln(‘Введите число для перевода:’); readln(s); if (CheckDotCount(s) = false) then begin writeln(‘Во введеном числа более 1 точки, что-то не так’); exit; end; writeln(‘Введите основание входной системы счисления:’); readln(base_in); if (checkSS(base_in, s) = false) then begin writeln(‘Некорректная система счисления или число для этой системы счисления’); exit; end; writeln(‘Введите основание выходной системы счисления:’); readln(base_out); if (checkSSR(base_out) = false) then begin writeln(‘Некорректная система счисления или число для этой системы счисления’); exit; end; s1 := getStringBeforeDot(s); s2 := getStringAfterDot(s); IntConverter(s1,base_in,base_out); DotConverter(s2,base_in,base_out); readln; end.

На PascalABC нет некоторых функций, зато есть другие.

Урок 32. Перевод чисел между системами счисления

Пишем программу: перевод в разные системы счисления

Версия для PascalABC

program test; var s, s1,s2 : string; // число для перевода base_in : integer; // Основание входной системы счисления base_out : integer; // Основание выходной системы счисления function CheckDotCount(s: string): boolean; // Проверка количества точек в числе var count, i : integer; begin count := 0; for i := 1 to Length(s) do if (s[i] = ‘.’) then inc(count); if (count > 1) then CheckDotCount := false else CheckDotCount := true; end; function IntToHex(ds: byte): string; const b: string = ‘0123456789ABCDEF’; begin if (b[(ds shr 4) + 1] = ‘0’) then Result:= b[(ds and $F) + 1] else Result:= b[(ds shr 4) + 1] + b[(ds and $F) + 1]; end; function HexToInt(s: string): Longword; var b: Byte; c: Char; begin Result := 0; s := UpperCase(s); for b := 1 to Length(s) do begin Result := Result * 16; c := s[b]; case c of ‘0’..’9′: Inc(Result, Ord(c) — Ord(‘0’)); ‘A’..’F’: Inc(Result, Ord(c) — Ord(‘A’) + 10); end; end; end; function checkSS(base : integer; s : string): boolean; var i: integer; flag : boolean; begin flag := true; for i := 1 to Length(s) do begin if (HexToInt(s[i]) >= base) then flag := false; end; if ((base > 16) or (base < 2)) then flag := false; Result := flag; end; function checkSSR (base : integer):boolean; begin if ((base >16) or (base < 2)) then Result := false else Result := true; end; function getStringBeforeDot(s:string): string; //pos : integer; begin if (Pos(‘.’,s) = 0) then Result := s else Result := Copy(s, 1,Pos(‘.’,s)-1); end; function getStringAfterDot(s: string):string; begin if (Pos(‘.’,s) = 0) then Result := » else Result := copy(s,Pos(‘.’,s)+1,Length(s)); end; procedure IntConverter(s:string; base_in : integer; base_out : integer); var n1,N,i,r1 : integer; d1 : array [0..255] of integer; begin n1 := Length(s); N := 0; for i := 1 to n1 do begin N:= N*base_in+HexToInt(s[i]); end; if (N = 0) then write (‘0’) else begin r1 := 0; while (N <>0) do begin d1[r1] := N mod base_out; N := N div base_out; inc(r1); end; for i:=r1-1 downto 0 do write(IntToHex(d1[i])); end; end; procedure DotConverter(s:string; base_in : integer; base_out : integer); var n2 , i, k2: longint; Nf : double; begin n2 := Length(s); if (n2 = 0) then begin writeln(); exit; end; write(‘.’); Nf := 0; for i := n2 downto 1 do begin Nf := (HexToInt(s[i]) + Nf) / base_in; end; k2 := 0; while ((Nf <> 0) AND (k2 < 20)) do begin inc(k2); write(IntToHex(Floor(Nf*base_out))); Nf := ((Nf*base_out)); end; end; begin writeln(‘Введите число для перевода:’); readln(s); if (CheckDotCount(s) = false) then begin writeln(‘Во введеном числе более 1 точки, что-то не так’); exit; end; writeln(‘Введите основание входной системы счисления:’); readln(base_in); if (checkSS(base_in, s) = false) then begin writeln(‘Некорректная система счисления или число для этой системы счисления’); exit; end; writeln(‘Введите основание выходной системы счисления:’); readln(base_out); if (checkSSR(base_out) = false) then begin writeln(‘Некорректная система счисления или число для этой системы счисления’); exit; end; s1 := getStringBeforeDot(s); s2 := getStringAfterDot(s); IntConverter(s1,base_in,base_out); DotConverter(s2,base_in,base_out); readln; end.

Читайте также:
Какие вкладки с инструментами содержит программа Microsoft word информатика

Внимание, PascalABC и, соответственно, его версия исполняемых файлов требует .Net Framework Версии 4. Он встроен в Windows 8, но его нужно включить в компонентах Windows.

Версия запущенная в Pascal ABC

Источник: pyatnitsev.ru

Перевод десятичного числа в любую систему счисления

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

Решение задачи на языке программирования Python

Алгоритм перевода десятичного числа в любую другую систему счисления заключается в последовательном целочисленном делении сначала самого десятичного числа, а потом получаемых частных на основание системы счисления, в которую переводится число. Из остатков такого деления собирается представление числа в новой системе счисления. В той, на основание которой происходило деление. Сбор остатков происходит с конца.

Например, перевод десятичных чисел 160 в восьмеричную и 18 в двоичную системы счисления будет выглядеть так:

160 / 8 = 20 | 0 20 / 8 = 2 | 4 2 / 8 = 0 | 2
16010 = 2408
18 / 2 = 9 | 0 9 / 2 = 4 | 1 4 / 2 = 2 | 0 2 / 2 = 1 | 0 1 / 2 = 0 | 1
1810 = 100102

Даже если использовать этот алгоритм для перевода десятичного числа в десятичную систему счисления будет получен верный результат.

150 // 10 = 15 | 0 15 // 10 = 1 | 5 1 // 10 = 0 | 1
15010 = 15010

Проблема появляется в тот момент, когда основание системы счисления начинает превышать 10. В таких случаях нам не хватает привычных символов цифр (0-9) и требуется ввод дополнительных символов для обозначения значений, соответствующих десятичным числам 10, 11, 12 и т. д. Для примера переведем десятичное число в шестнадцатеричную систему счисления:

700 // 16 = 43 | 12 (C) 43 // 16 = 2 | 11 (B) 2 // 16 = 0 | 2
70010 = 2BC16

Десятичные остатки 12 и 11 при формировании шестнадцатеричного числа должны быть представлены одним разрядом. В таких случаях в качестве цифр, чье значение больше 9-ти, используются английские буквы. Так числу 10 будет соответствовать символ A , числу 11 — B и т. д.

Читайте также:
Dark project kd87a программа для настройки

Таким образом, при написании программы перевода десятичного числа в любую систему счисления мы должны предусмотреть подмену остатков на соответствующие им символы, если эта замена требуется.

Будем усложнять программу поэтапно и сначала напишем вариант кода, который переводит не в любую систему счисления, а только с основанием до 10-ти.

num = int(input()) base = 0 while not (2 base 9): base = int(input(«Основание (2-9): «)) new = » while num > 0: remainder = num % base new = str(remainder) + new num = num // base print(new)

В цикле сначала вычисляется остаток. Далее присоединям его спереди к строковой переменной new , в которой хранится представление числа в новой системе счисления. Последним действием присваиваем переменной num частное от целочисленного деления прежнего значения num на основание системы счисления.

Поскольку в языке программирования Python есть функция divmod , сократим код, объединив нахождение остатка и целочисленное деление:

. while num > 0: num, remainder = divmod(num, base) new = str(remainder) + new .

Вызов divmod(num, base) возвращает кортеж из частного и остатка от деления num на base . Далее частное присваивается num , остаток — remainder .

Теперь напишем программу, которая переводит число исключительно в шестнадцатеричную систему счисления. Для хранения символов, которыми будут заменяться двузначные остатки, используем строку из этих символов.

num = int(input()) base = 16 letters = ‘ABCDEF’ new = » while num > 0: num, remainder = divmod(num, base) if remainder > 9: letter_id = remainder — 10 remainder = letters[letter_id] new = str(remainder) + new print(new)

Числу 10 соответствует символ A . Поэтому если остаток равен десяти, то letter_id будет равно нулю. Символ под индексом 0 в строке букв — как раз A . Если остаток равен 15-ти, то letter_id будет равно пяти, а letters[5] вернет F .

Программу можно упростить, если в строку символов добавить цифры. В этом случае остатки будут точно соответствовать индексам, под которыми находятся соответствующие им символы.

num = int(input()) base = 16 letters = ‘0123456789ABCDEF’ new = » while num > 0: num, remainder = divmod(num, base) new = letters[remainder] + new print(new)

На этом этапе должно стать понятно, как написать программу конвертации десятичного числа в почти любую систему счисления. Достаточно немного подправить код перевода в шестнадцатеричную систему, дописав в строку дополнительный набор символов, а не заканчивать ее на F .

Чтобы не хранить в программе строку большой длины и избежать ошибки из-за нечаянно пропущенного какого-нибудь символа, вернемся к варианту, в котором остатки больше девяти заменяются в теле условного оператора. При этом буквы будем брать не из определенной в коде строки, а из встроенной таблицы символов.

num = int(input()) base = 0 while not (2 base 36): base = int(input(«Основание (2-36): «)) new = » while num > 0: num, remainder = divmod(num, base) if remainder > 9: letter = remainder — 10 remainder = chr(ord(‘A’) + letter) new = str(remainder) + new print(new)

Вызов ord(‘A’) возвращает код буквы A в таблице Unicode. К этому коду-числу мы прибавляем смещение по алфавиту (значение letter ). С помощью функции chr() получаем соответстующую коду букву.

def convert_integer(decimal, radix): if radix > 36: return «Основание системы счисления должно быть не больше 36-ти» number = » while decimal > 0: decimal, remainder = divmod(decimal, radix) if remainder > 9: remainder = chr(ord(‘A’) + remainder — 10) number = str(remainder) + number return number num = int(input(«Десятичное число: «)) base = int(input(«Основание (2-36): «)) print(convert_integer(num, base))

Ограничение по основанию в 36 связано с количеством букв в английском алфавите. Их 26, плюс десять цифр. Расширить диапазон оснований можно за счет взятия недостающих символов из какой-либо другой части таблицы Unicode. Например, можно добавить к условному оператору ветку elif с условием remainder > 35 , а в теле вычитать из remainder 36.

Читайте также:
Доступная среда государственная программа требования

Однако написать программу, которая переводит десятичное число в абсолютно любую систему счисления нельзя. Иначе надо суметь решить задачу генерации случайного символа, который не должен быть похож ни на какой из полученных ранее.

X Скрыть Наверх

Решение задач на Python

Источник: younglinux.info

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

Двоичные часы

Недавно решал задачи по криптографии, и возникла необходимость переводить очень большие числа из одной системы счисления в другую. С двоичной, восьмеричной, десятичной и шестнадцатеричной системой справляется и стандартный калькулятор ОС. Но он не рассчитан на числа большой длины. А мне как раз необходимо работать с числами длиной >1000 знаков.
Для этих целей решил написать небольшой консольный конвертер, позволяющий работать с числами любой длины и любой системы счисления от 2 до 36.

Требования:

• Конвертер должен работать с числами любой длины.
• Конвертер должен работать в любой системе счисления от 2 до 36.
• Конвертер должен уметь работать с файлами.

Реализация:

Писать решил на языке C++. Люблю этот язык, да и перевести исходники в другой язык из C++ не составляет особого труда.

Написал следующий класс:

class Converter < private: //Вектор содержит исходное число vectora; //Исходная система счисления int iriginal; public: //Конструктор, содержит 2 параметра: строка исходного числа, исходная система счисления Converter(string str, int original)< this->iriginal = original; //Заносит числа исходного числа в вектор for ( int i=0; i < str.length(); i++ )< this->a.push_back(charToInt(str[i])); > > //Переводит символ в число, вместо некорректных символов возвращает -1 int charToInt(char c)< if ( c >= ‘0’ c iriginal )< return c — ‘0’; >else< if ( c >= ‘A’ c iriginal )< return c — ‘A’ + 10; >else < return -1; >> > //Переводит число в символ char intToChar(int c)< if ( c >= 0 c else < return c + ‘A’ — 10; >> //Получает следующую цифру числа в новой системе счисления int nextNumber(int final)< int temp = 0; for ( int i = 0; ia.size(); i++)< temp = temp*this->iriginal + this->a[i]; a[i] = temp / final; temp = temp % final; > return temp; > //Возвращает true — если массив состоит из одних нулей и false в противном случае bool zero()< for ( int i=0; ia.size(); i++ ) < if ( a[i] != 0 )< return false; >> return true; > //Конвертирует исходное число в заданную систему счисления string convertTo(int final) < vectorb; int size = 0; do < b.push_back(this->nextNumber(final)); size++; >while( !this->zero() ); string sTemp=»»; for (int i=b.size()-1; i>=0; i—) < sTemp += intToChar(b[i]); >return sTemp; > >;

Код получился достаточно простой

Далее прикрутил его в проект:

//Адрес файла, содержащего исходное число string inputFile = argv[1]; //Исходная система счисления int original = atol(argv[2]); //Требуемая система счисления int final = atol(argv[3]); //Строка, содержащая исходное число string origNumber; ifstream fin(inputFile.c_str()); if ( fin.is_open() )< fin >> origNumber; >else < cout fin.close(); Converter conv(origNumber,original); //Если не был задан файл для вывода, то результат отобразиться на экране if ( argc > 4 )< //Адрес файла для записи нового числа string outputFile = argv[4]; ofstream fout(outputFile.c_str()); if ( fout.is_open() )< fout else < cout >else

Код, конечно, далек от идеала, но зато все просто и понятно.

Теперь можно протестировать.

Конвертер готов, теперь осталось его испытать. Создаю файл, содержащий число, представляющее из себя тысячу девяток.
Запускаю в консоли:
Запуск конвертера в консоли
Конвертер удачно создает файл output.txt, содержащий число, длиной 3322 символа.
Теперь выведу его на экран, для этого достаточно не задавать файл для вывода.
Вывод результата на экран
Так же можно задавать исходное число прямо в консоли
Вывод результата на экран 2

Вывод:

Если нужно конвертировать что-то очень большое, то данный конвертер отлично для этого подойдет. Отсутствие интерфейса позволяет без изменения запускать написанный код на любой платформе. А консоль забывать нельзя, будь то windows или Linux…
Скачать проект(VS 2008) можно здесь.

Источник: habr.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru