Stefan Adrianus
Stefan Adrianus

Reputation: 51

how to convert hexa to dec using delphi and hex to octal?

function HexToDec(Str: string): Integer;
var
i, M: Integer;
begin
Result:=0;
M:=1;
Str:=AnsiUpperCase(Str);
for i:=Length(Str) downto 1 do
begin
case Str[i] of
  '1'..'9': Result:=Result+(Ord(Str[i])-Ord('0'))*M;
  'A'..'F': Result:=Result+(Ord(Str[i])-Ord('A')+10)*M;
end;
M:=M shl 4;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if Edit1.Text<>'' then
Label2.Caption:=IntToStr(HexToDec(Edit1.Text));
end;

How to using it without function, because i want to call the result again in other line, and how about hexa to octal ? am i must conver from hexa to dec and then dec to octal?

Upvotes: 1

Views: 2535

Answers (2)

Dsm
Dsm

Reputation: 6013

My first comment would be that you are not converting hex to decimal with your function (although you are converting to decimal as an intermediate) but rather hex to integer. IntToStr then converts integer to base 10, effectively. To generalise what you want then I would create two functions - strBaseToInt and IntToStrBase where Base is meant to imply e.g. 16 for hex, 10 for dec, 8 for octal, etc., and assuming the convention adopted by hex that A=10, and so on but to (possibly) Z = 35 making the maximum base possible 36.

I don't handle + or - but that could be added easily.

In the reverse funtion, again for simplicity of illustration I have ommitted supporting negative values.

Edit

Thanks to Rudy for this improvement

Edit 2 - Overflow test added, as per comments

function StrBaseToInt(const Str: string; const Base : integer): Integer;
var
  i, iVal, iTest: Longword;
begin
  if (Base > 36) or (Base < 2) then raise Exception.Create('Invalid Base');
  Result:=0;
  iTest := 0;
  for i:=1 to Length(Str) do
  begin
    case Str[i] of
      '0'..'9': iVal := (Ord(Str[i])-Ord('0'));
      'A'..'Z': iVal := (Ord(Str[i])-Ord('A')+10);
      'a'..'z': iVal := (Ord(Str[i])-Ord('a')+10);
      else raise Exception.Create( 'Illegal character found');
    end;
    if iVal < Base then
    begin
      Result:=Result * Base + iVal;
      if Result < iTest then  // overflow test!
      begin
        raise Exception.Create( 'Overflow occurred');
      end
      else
      begin
        iTest := Result;
      end;
    end
    else
    begin
      raise Exception.Create( 'Illegal character found');
    end;
  end;
end;

Then, for example your HexToOct function would look like this

function HexToOct( Value : string ) : string;
begin
  Result := IntToStrBase( StrBaseToInt( Value, 16), 8 );
end;

Additional

A general function would be

function BaseToBase( const Value : string; const FromBase, ToBase : integer ) : string;
begin
  Result := IntToStrBase( StrBaseToInt( Value, FromBase ),ToBase );
end;

Upvotes: 2

Rudy Velthuis
Rudy Velthuis

Reputation: 28846

Delphi can do this already, so you don't need to write a function parsing the number. It is quite simple, actually:

function HexToDec(const Str: string): Integer;
begin
  if (Str <> '') and ((Str[1] = '-') or (Str[1] = '+')) then
    Result := StrToInt(Str[1] + '$' + Copy(Str, 2, MaxInt))
  else
    Result := StrToInt('$' + Str);
end;

Note that that also handles negative hex numbers, or numbers like +$1234.

How to using it without function, because i want to call the result again in other line ?

If you want to re-use the value, assign the result of HexToDec to a variable and use that in IntToStr.


FWIW, in your function, there is no need to call AnsiUpperCase, because all hex digits fall in the ASCII range anyway. A much simpler UpperCase should work too.

Upvotes: 6

Related Questions