Сложение шестнадцатеричных чисел

За вознаграждение или нахаляву (если повезёт)

Модераторы: Хыиуду, MOTOCoder, Medved, dr.Jekill

sonic007
Сообщения: 5
Зарегистрирован: 21 июн 2008, 20:34

21 июн 2008, 20:36

помогите реализовать задачу

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

нашел подобную для десятичных чисел, а как реализовать для шестнадцатеричных - не шарю.. Уважаемые гуру. помогите. иначе не засчитают мне практику..
program a1;
uses crt;
var a,b:string;
i,j,k,m:integer; c,d,x:array[1..253] of integer;
begin
clrscr;
readln(a);
readln(b);
j:=length(a);
for i:=1 to length(a) do
begin
val(a,c[j],m); j:=j-1;
end;
j:=length(b);
for i:=1 to length(b) do
begin
val(b,d[j],m); j:=j-1;
end;
if length(a)<length(b) then k:=length(b) else k:=length(a);
k:=k+1;
for i:=1 to k do
x:=0;
for i:=1 to k do
begin
x:=c+d+x;
if x>=10 then
begin
x[i+1]:=x[i+1]+1;
x:=x mod 10;
end;
end;
if x[k]=0 then k:=k-1;
for i:=k downto 1 do write(x[i]);
readkey;
end.
Serge_Bliznykov
Сообщения: 366
Зарегистрирован: 31 авг 2007, 03:06

22 июн 2008, 02:09

Код: Выделить всё

var
  f : text;
  SumHex : integer;
  s : string;
  i, OneHexNumber : integer;
begin
  assign(f, 'h1.hex');
  reset(f);
  SumHex  := 0;
  while Not eof(f) do begin
    Readln(f,s);
    s := '$'+s;
    Val(s, OneHexNumber,i);
    if i=0 then 
     SumHex := SumHex + OneHexNumber;
  end;
  
  WriteLn('Sum of hex = ',SumHex:1)
  
end. 
sonic007
Сообщения: 5
Зарегистрирован: 21 июн 2008, 20:34

22 июн 2008, 04:05

это было бы слишком легко для сдачи практики..

забыл сказать самое главное: программа должна работать со сверхбольшими шестнадцатеричными числами типа fffffffffffffffffffffffffffffffffffffff

тип данных real, extended не использовать..

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

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

поможете начинающему ?
BHy4ok
Сообщения: 229
Зарегистрирован: 01 май 2007, 09:03
Откуда: г.Находка
Контактная информация:

22 июн 2008, 07:56

sonic007 писал(а):это было бы слишком легко для сдачи практики..

Как говорится - "краткость сестра таланта."
Это самый рациональный способ решения твоей задачи, перевод из символьного кода в числовой (переменная "Val"). Следовательно тот метод решения который предлагаешь ты не есть рациональный.
тип данных real, extended не использовать.
Дело в том, что если использовать тип: integer(longint), то они могут быть лишь в промежутке: -2147483648..2147483647, что есть - 7FFFFFFF

Другими словами со "сверхбольшими" числами сможет работать тип "real".
вот только не шарю я как переводить сверхбольшие числа из одной системы в другую..
Не имеет значения какая система счисления все дело в типе данных. (об этом выше)
< L3X. (ICQ: 8721378, Mail - l3x@list.ru)
Serge_Bliznykov
Сообщения: 366
Зарегистрирован: 31 авг 2007, 03:06

22 июн 2008, 09:20

sonic007, ну, во-первых, условия задания надо приводить сразу и ПОЛНОСТЬЮ!!!
вот, например, "сверхбольшими шестнадцатеричными" - сколько значащих цифр - 20, 30, 100, 255 ? (надеюсь, что хоть не больше 255?!?!)
&quot писал(а):вот только не шарю я как переводить сверхбольшие числа из одной системы в другую..
да ну брось - не так ты решаешь эту задачу.
Кто тебе вообще сказал, что надо эти числа переводить из одной системы в другую?
и вообще, задачка на "длинную арифметику" - поищи на форуме и в интернете.
Смысл в том, что заводится массив (или строчка - кому как удобнее, по сути строка — это тоже массив из char), размерность массива должна покрывать самое большое число, потом считываешь своё число, помещаешь в массив, обязательно начиная с младших разрядов в конец массива и двигаясь к старшим разрядам числа, индекс массива уменьшая. А потом организовать суммирование в столбик. я бы это банально сделал прямо с шестнадцатеричным числами...
В конце выдал бы результат прямо в шестнадцатеричном виде (ибо разрядность стандартных типов данных явно не хватит для 200значного hex числа).

Удачи.
Vasilisk
Сообщения: 111
Зарегистрирован: 13 фев 2004, 18:43

22 июн 2008, 14:09

Как всё-таки люди извращаются, лишь бы только самим задачу не решать :) Задачка - очень простая, она - на прямое запрограммирование алгоритма сложения столбиком, а система счисления - здесь вовсе не причём. Алгоритм сложения столбиком помнишь? Вот, как раз его и надо записать - в одной строке циферки, в другой строке циферки, а третья строка - сумма циферок в двух предыдущих.

Предыдущий оратор правильно назвал возникающие при этом проблемы - оба числа при этом нужно нормализовать (привести к одинаковой длине и положению точки, разделяющей дробные и целые разряды), складывать их нужно побайтно от младших к старшим... Ну что, погнали? Одну строчку пишешь ты, другую - я? [единственная проблема - я на Паскале не умею программы писать, на Паскале я только читаю...]
sonic007
Сообщения: 5
Зарегистрирован: 21 июн 2008, 20:34

22 июн 2008, 14:18

да. я уже понял, что надо сделать суммирование столбиком.. сейчас попробую написать.. посмотрим что получится
Vasilisk
Сообщения: 111
Зарегистрирован: 13 фев 2004, 18:43

22 июн 2008, 17:00

Ну, ты заходи, если что. Лет пятнадцать назад я такую библиотеку на ассемблере писал. Долго искал алгоритм деления. Спустя двенадцать лет нашёл... в исходниках PHP. И там же - ссылка на то, что взят этот алгоритм из учебника Кнута :)
sonic007
Сообщения: 5
Зарегистрирован: 21 июн 2008, 20:34

23 июн 2008, 04:27

Вот мне помог товарищ Humanoid с cyberforum за что ему большой респект.

привожу код.. может кому то понадобится


[syntax='Delphi']
Const HexTab : array[0..15] of char = ('0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F');
Var Res : Array[1..100] of byte;
I : Integer;
S : String;
F : Text;

Procedure Sum(V : String); { Процедура, которая прибавляет к результату новое значение }
Var A : Byte;
PosR : Integer;
Begin
For I := 1 to Length(V) do { Переводим все буквы в верхний регистр и ищем ошибки }
Begin
If V in['a'..'f'] then Dec(V,32); { Если этот симвл - маленькая буква, то уменьшаем ее значение на 32 (переводим в верхний регистр) }
If not(V in['0'..'9','A'..'F']) then { Если это не шестнадцатиричное значение, то ошибка }
Begin
WriteLn(V,' is not hex!');
Exit;
End;
End;
For I := Length(V) downto 1 do
Begin
If V>'9' then
A := Ord(V)-48-7
else
A := Ord(V)-48;
PosR := 100-Length(V)+I; { Выщитываем текущую позицию в массиве Res }
Res[PosR] := Res[PosR] + A; { Прибавляем значение к текущей позиции }
If Res[PosR]>15 then { ГДе то в этой части кода находится баг }
Begin
Res[PosR-1] := Res[PosR-1] + 1; { Увеличиваем на 1 старшую позицию }
Res[PosR] := Res[PosR] - 16; { А в этой оставляем только остаток }
End;
End;
End;

Begin
For I := 1 to 100 do Res := 0; { Обнуляем результат }

Assign(F,'a.txt');
Reset(F);
While not Eof(F) do
Begin
ReadLn(F,S); { Читаем очередное значение }
If S='' then Continue; { Нефиг обрабатывать пустые строки }
Sum(S); { Прибавляем очередную строку к результату }
End;
Close(F);

{ Готовим значение, что бы вывести на экран }
S := '';
For I := 1 to 100 do
Begin
S := S + HexTab[Res]; { Перевести из вида целого числа 0..15 в строковый вид '0'..'F' }
End;
While (S<>'') and (S[1]='0') do Delete(S,1,1); { Убираем все нули из начала }
WriteLn(S); { Выводим на экран полученный результат в шестнадцатиричном виде }
End.
[/syntax]

в проге есть небольшая бага : если слаживать числа типа fff + число (т.е. при необходимости ввести новый разряд) , то перенос не работает.. в символе сохраняется значение "16" и дальше идет неправильное суммирование..

в общем посмотрю завтра что нужно подправить.
airyashov
Сообщения: 416
Зарегистрирован: 02 ноя 2007, 10:31

23 июн 2008, 08:39

ошибка будет, если число которое прибавляется на текущем шаге меньше (по кол-ву цифр) текущего результата
Ответить