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

Ответить

Код подтверждения
Введите код в точности так, как вы его видите. Регистр символов не имеет значения.

BBCode ВКЛЮЧЁН
[img] ВКЛЮЧЁН
[url] ВКЛЮЧЁН
Смайлики ОТКЛЮЧЕНЫ

Обзор темы
   

Развернуть Обзор темы: Сложение шестнадцатеричных чисел

Приветикифыва

saurlhali » 01 сен 2013, 14:29

Отличный сайт у вас, красивая шапка
http://pulsz.ru/

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

sonic007 » 23 июн 2008, 20:07

Рабочая программа.

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

Uses crt;
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);  { adding new value to result }
  Var A : Byte;
      PosR : Integer;
  Begin
    For I := 1 to Length(V) do  { convert to uppercase}
    Begin
      If V[i] in['a'..'f'] then Dec(V[i],32); { if letter is lowcase convert to uppercase }
      If not(V[i] in['0'..'9','A'..'F']) then  { display error if not hex }
      Begin
        WriteLn(V,' is not hex!');
        Exit;
      End;
    End;
    For I := Length(V) downto 1 do
    Begin
      If V[i]>'9' then  { convert '0'..'F' into 0..15 }
        A := Ord(V[i])-48-7
      else
        A := Ord(V[i])-48;
	
      PosR := 100-Length(V)+I;  { current position in massive Res }
      Res[PosR] := Res[PosR] + A;  { adding valueto current position }
      If Res[PosR]>15 then    { if too big, add 1 to next position }
      Begin
        Res[PosR-1] := Res[PosR-1] + 1; { inc next pos by 1 }
        Res[PosR] := Res[PosR] - 16;  { div}
      End;
    End;
    {------------------ Здесь устраняем ошибку по переносу разрядов }
	For I := 100 downto 2 do
    Begin
      If Res[i]>15 then
      Begin
        Res[I-1] := Res[I-1] + 1;
        Res[i] := Res[i] - 16;
      End;
    End;
    {--------------------}
  End;

Begin
clrscr;
  For I := 1 to 100 do Res[i] := 0;  { make res 0 }

  Assign(F,'a.txt');
  Reset(F);
  While not Eof(F) do
  Begin
    ReadLn(F,S);   { reading next value }
    If S='' then Continue;  { skip empty lines }
    Sum(S);  { adding new line to result }
  End;
  Close(F);

{preparing for output }
  S := '';
  For I := 1 to 100 do
  Begin
    S := S + HexTab[Res[i]];  { convert from 0..15 to '0'..'F' }
  End;
  While (S<>'') and (S[1]='0') do Delete(S,1,1);  { delete 0 from beginning}
  WriteLn(S);  { write hex }
  readln;
End.

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

airyashov » 23 июн 2008, 08:50

[syntax=Delphi]
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;

For I:= 100-Length(V) downto 2 do
if Res>15 then
Begin
Res[I-1] := Res[I-1] + 1; { Увеличиваем на 1 старшую позицию }
Res := Res - 16; { А в этой оставляем только остаток }
End;
[/syntax]

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

airyashov » 23 июн 2008, 08:39

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

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

sonic007 » 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" и дальше идет неправильное суммирование..

в общем посмотрю завтра что нужно подправить.

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

Vasilisk » 22 июн 2008, 17:00

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

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

sonic007 » 22 июн 2008, 14:18

да. я уже понял, что надо сделать суммирование столбиком.. сейчас попробую написать.. посмотрим что получится

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

Vasilisk » 22 июн 2008, 14:09

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

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

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

Serge_Bliznykov » 22 июн 2008, 09:20

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

Удачи.

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

BHy4ok » 22 июн 2008, 07:56

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

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

Другими словами со "сверхбольшими" числами сможет работать тип "real".
вот только не шарю я как переводить сверхбольшие числа из одной системы в другую..
Не имеет значения какая система счисления все дело в типе данных. (об этом выше)

Вернуться к началу