HexToDec - пример длинной арифметики. Как длинное (до 300 символов) Шестнадцатеричное число преобразовать в Десятичное
Язык реализации – Си.
Спецификацию (т.е. задание) найдете в скаченном архиве...
Ответим себе на принципиальные вопросы:
- Сколько разрядов необходимо иметь в десятичном числе, чтобы уместилось число в 300 шестнадцатеричных символов?
- Какие функции «длинной арифметики» следует написать, чтобы преобразование проводилось на
уровне разрядов (т.к. понятно, что столь длинное число целиком обработать не возможно)?
- Есть ли необходимость обеспечивать возможность работы программы с информацией из текстовых файлов?
Пример для трехзначного числа 70F :
Путем несложных вычислений я выбрал для себя число 370 (ведь с округленными приятнее работать), как число десятичных разрядов, в которых гарантированно уместится 300-разрядное шестнадцатеричное. Такой размерности будет массив Dec для хранения десятичных символов.
Поскольку в формуле есть суммирование не обойтись без функции:
char* SUM(char* dec1, char* dec2); //суммирование двух символьных строк
Получая два указателя на символьные массивы, она должна на выходе выдать указатель на строку символов,
являющуюся суммой исходных чисел-параметров.
Далее, в формуле есть возведение в степень числа 16, поэтому:
char* pow16in(int pw); //строка десятичных символов = 16 в степени pw
Получая параметр pw со значениями от 0 до 300, она должна на выходе выдать указатель на строку десятичных
символов (массив размерностью 370).
{ signed char rez[limDec];
int i;
strcpy(rez, "1"); //1 копирую в результат
for(i=0;i<pw;i++)
strcpy(rez, MultiOn(rez, 16)); //многократное умножение на 16
return &rez[0];
}
И последнее, в формуле, действие: умножение на сам 16-ричный символ (число от 0 до 15):
char* MultiOn(char* dec1, int num); //строка символов умножается на num
Функция возвращает указатель на новую строку десятичных символов, равную результату умножения.
{ signed char rez[limDec];
int i, su, len, carri=0; //длина строки-числа и перенос
len=strlen(dec1);
strcpy(rez, dec1); //большую строку-число копирую в результат
for(i=0;i<len;i++)
{ su = SymbolToInt(dec1[i])*num + carri;
carri=(su>9) ? (su / 10) : 0 ;
rez[i]= IntToSymbol(su % 10);
}
while (carri>0) //возможна цепочка переносов
{ rez[i]=IntToSymbol(carri % 10);
rez[i+1]='\0';
carri/=10;
i++;
}
return &rez[0];
}
У массивов, хранящих 16-ричные числа, старший разряд я располагал слева (так как приходится читать эти числа с клавиатуры или из файла, а людям привычней … сами понимаете…).
У массивов, хранящих 10-чные символы (т.е. числа) слева будет находиться младший (или нулевой) разряд. Так удобней проводить вычисления. Пусть разрядность числа растет вправо. А когда придет черед вывести результат, то выведем массив в обратном порядке.
Функция чтения 16-ричного числа из файла полезна. Особенно для больших чисел. Да и в спецификации была указана.
Так что делаю… Остается скомпоновать программу.
Каждый, сам по себе, шаг – не сложный. Потратив некоторое время, любой студент (как и школьник в свое время) с арифметикой справится.
Еще пример из Длинной Арифметики на С++ смотрите, качайте...
Тестируйте. Кому интересен код – высылаю хоть целиком, хоть по частям…
Другие примеры на языках «C»,«C++»,«C#»
Поделиться в соц сетях: