[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]