[Back to NUMBERS SWAG index]  [Back to Main SWAG index]  [Original]


program hexlong;

const hexstr = '7fffffff';
const hexstr1 = '80000000';

  function Hex2Long(S: string): Longint;
  var
    Temp: Longint;
    Err: Integer;
  begin
    Insert('$',S,1);
    Val(S, Temp, Err);
    Hex2Long := Temp;
  end;

begin
  writeln (hexstr, ' = ', hex2long(hexstr));
  writeln ('MAXLONGINT = ', maxlongint);
  writeln (hexstr1, ' = ', hex2long(hexstr1));
  readln;
end.

------------------------------------------------------------------------

7fffffff = 2147483647
MAXLONGINT = 2147483647
80000000 = -2147483648

------------------------------------------------------------------------

The values output are 100% correct.

Mike Phillips
INTERNET:  phil4086@utdallas.edu


procedure UnsignedStr(L:longint; var S:string); assembler;
var
 TS:array[0..9] of char; { Temp string, it's stored backwards }
asm
 mov di,ds     { Save DS }
 mov si,ss     { Set DS:SI to TS }
 mov ds,si
 lea si,TS[10]
 mov bx,10     { Divide by 10 }
 mov cx,word ptr [L]    { Get L to ax:cx }
 mov ax,word ptr [L+2]
@NotFin:
 xor dx,dx     { Divide ax:cx by 10 to cx:ax, remainder in dx }
 div bx
 xchg ax,cx
 div bx
 add dl,48     { Convert remainder to ASCII }
 dec si
 mov [si],dl   { Save in TS }
 xchg ax,cx    { Swap ax and cx to prepare for next divide }
 or ax,ax      { Already zero? }
 jnz @NotFin   { No -> continue }
 or cx,cx      { Also for high word... }
 jnz @NotFin
 lea cx,TS[10] { Get length of string }
 sub cx,si
 mov dx,di     { Move saved DS to dx }
 les di,S      { Get pointer of result string }
 cld
 mov al,cl     { Store length }
 stosb
 rep movsb     { Copy ASCII string }
 mov ds,dx     { Restore DS }
end;

var
 I:longint;
 J:integer;
 S:string;
begin
 Val('$FFFFFFFF',I,J);
 UnsignedStr(I,S);
 WriteLn(S,',',J);
end.

Function Hex2Long(S:String):LongInt; Assembler; 
 
Asm 
           les di,[S]
           xor bx,bx 
           mov dx,bx 
           mov cl,[es:di] 
           inc di 
@@CnvLoop: mov al,[es:di]
           inc di 
           mov ah,'0' 
           cmp al,'9' 
           jbe @@Cnv2Num 
                  mov ah,'a'+10     
                  cmp al,'a' 
                  jae @@Cnv2Num 
           mov ah,'A'+10
@@Cnv2Num: sub al,ah 
           shl dx,4 
           mov ch,bh 
           shr ch,4
           add dl,ch 
           shl bx,4 
           add bl,al 
           dec cl 
           jnz @@CnvLoop 
           mov ax,bx 
End; 
 
This is untested, off-the-top-of-my-head code, but it should work.  If
it doesn't just let me know and I will write a tested version for you.

John Baldwin
jbaldwin@freedomnet.com

{----------------------------------------------------------------}

PROGRAM Hexadecimal_To_Long_Converter;

USES Crt;

FUNCTION IsXDigit(CONST c: char): boolean;
{ -- TRUE iff C is a hexadecimal digit, i.e.
  -- C IN ['A' .. 'F', 'a' .. 'f', '0' .. '9']. }
INLINE($5B/$80/$FB/$30/$72/$21/$80/$FB/$39/$77/$02/$EB/$16/$80/$FB/$41/$72/
       $07/$80/$FB/$46/$77/$02/$EB/$0A/$80/$FB/$61/$72/$09/$80/$FB/$66/$77/
       $04/$B0/$01/$EB/$02/$B0/$00);

{ -- Oh alright, I copied the above routine from one of my units ... }

FUNCTION HexChar2Byte(CONST c: char): byte;
{ -- Convert a hex digit to its decimal value.
  -- Note: no argument checking. }
BEGIN IF c IN ['0' .. '9']
      THEN HexChar2Byte:=byte(c) - 48
      ELSE HexChar2Byte:=byte(upcase(c)) - 55
END;

TYPE str8 = STRING[8];  { -- Hex strings in TP cannot exceed 8 characters. }

FUNCTION Hex2Long(CONST St: str8; VAR longvalue: longint): boolean;
{ -- Will attempt to convert a hexadecimal string to its decimal value.
  -- If this is succesful, the function result is TRUE, and the computed
  -- value is in LONGVALUE.
  -- If the routine fails (i.e, ST contains bad characters), FALSE is
  -- returned and LONGVALUE is undefined. }
VAR power_of_16: longint;
    j          : byte;
BEGIN Hex2Long:=FALSE;  { -- Assume failure. }
      FOR j:=1 TO length(St) DO IF NOT IsXDigit(St[j]) THEN exit;

      {$Q-  -- Necessary but harmless. }
      longvalue:=0; power_of_16:=1;
      FOR j:=length(St) DOWNTO 1
      DO BEGIN inc(longvalue, HexChar2Byte(St[j]) * power_of_16);
               power_of_16:=power_of_16 * 16
         END;
      {$Q+  -- "Pop all your pushes". }

      Hex2Long:=TRUE
END;

{ -- Main: }

VAR St: str8;
    L : longint;

BEGIN clrscr;
      REPEAT gotoxy(1, 2); ClrEol;
             write('Hex-string: '); readln(St);
             gotoxy(20, 2);
             IF Hex2Long(St, L)
             THEN write(' --> ', L:1)
             ELSE write(#7'Not a hex number ...');
             readkey
      UNTIL St = ''
END.

The principle is this:

decimal: 357 = 7*10^0 + 5*10^1 + 3*10^2
hex    : a9f = f*16^0 + 9*16^1 + a*16^2

in which "^" is the exponentiation operator.

For the mathematically challenged among you:
X^0 = 1 (any X), and X^1 = X (ditto).

{-------------------------------------   LEE BARKER -------------------- }
function hex2bin (s:string):longint;
  const h : array[0..15] of char = '0123456789ABCDEF';
        i,j : integer;
        x : longint;
  begin
    x := 0;
    for i := 1 to length(s) do
    begin
      j := pos(upcase(s[i]),h) -1;
        if j<0 then exit;             { error in str }
        if x and $F0000000 <> 0 then exit; { overflo }
      x := (x shl 4) + j;
    end;
    hex2bin := x;
  end;

[Back to NUMBERS SWAG index]  [Back to Main SWAG index]  [Original]