[Back to NUMBERS SWAG index] [Back to Main SWAG index] [Original]
{
> How does the following Function make a Word into Hex:
- Dissection:
}
Type
Str4 : String[4];
Function WordtoHex(W : Word) : St4
Var
HexStr : St4;
Function Translate(B : Byte) : Char;
{ This Function takes a number from 0 to 15 and makes it into a hex digit.}
begin
if B < 10 then
{ if it's 0..9 }
Translate := Chr(B + 48)
{ These statements use math on Characters... ascii 48 is '0'.
Could have been written: Translate := Chr(B + ord('0')) }
else
Translate := Chr(B + 55);
{ This one is For letters A~F. ascii 55 isn't anything, but if you add
$A (10) to 55 you get 65, which is the ascii code For 'A'
This could have been written: Translate := Chr(B + ord('A')-$A); }
end;
begin
HexStr := ' ';
HexStr := HexStr + Translate(Hi(W) shr 4);
{ Hi(W) takes the high Byte of Word W.
shr 4 means the same as divide by 16...
What they're Really doing here is taking each nibble of the hex Word
and isolating it, translating it to hex, and adding it to the String. }
HexStr := HexStr + Translate(Hi(W) and 15);
HexStr := HexStr + Translate(Lo(W) shr 4);
HexStr := HexStr + Translate(Lo(W) and 15);
WordtoHex := HexStr;
end;
{
> I am learning Pascal and don't understand something. How
> does the following Function make a Word into Hex:
It doesn't, at least not as present! But if you changes two things, maybe
spelling-errors, it will work. This is a bit hard to explain and grasp, because
it involves operations at a less abstract level than the one that you usually
work on in TP. Remember, when a number is stored in memory, it's stored binary,
hexadecimal notion is just For making it easier For man to read. I don't know
if you know how to Write and read binary- and hexadecimal-numbers, in Case you
don't know it's all here...
On PC, a Word, in the range 0 to 65535, has 16 bits. A Word written in binary
notion For this reason contains 16 digits, 0's or 1's! But a Word written in
hexadecimal notion contains 4 digits. Simple math tells us that one digit in
hex-notion is equal to four digits binary. Four digits binary gives 16
combinations (2^4). ThereFore, each hexadecimal digit must be able to contain
values from decimal 0-decimal 15, _in one digit_! Our normal digits, 0-9, isn't
sufficient For this, we must use 6 other digits. The designers of this system
choosed A-F as the extra digits. This means, in hex the digits are 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, A, B, C, D, E and F. Hanging on?
> Function WordtoHex(W : Word) : St4
Compile-time error: You must have a semicolon after the Function header-line.
> Var
> HexStr : St4;
> Function Translate(B : Byte) : Char;
> begin
> if B < 10
> then
> Translate := Chr(B + 48)
> else
> Translate := Chr(B + 55);
> end;
This is clearer as:
if b < 10
then Translate := Chr(b+ord('0'))
else Translate := Chr(b+ord('A')-10);
Think about the first Case, when b < 10, if b were 0, the expression would be
'0' plus 0, '0'!. if b were 1, it's '0' plus 1, '1'!. This works because in the
ASCII-table the numbers are sequential ordered. But '0' plus 10 would be ':',
because it happens to be after the numbers.
then, when we want 'A'-'F, we would need to start from 'A'. But we can't add 10
to 'A' For getting 'A' and 11 For getting 'B' and that like. First we must make
the value relative 'A'. Because the values that we're working on here is in the
range 10 to 15, we can decrease it With 10 and get 0 to 5. then is OK to use
them relative 'A'. As beFore, 'A' plus 0 is 'A', 'A' plus 1 is 'B', and so on.
However, this routine has no safety check, it will gladly return 'G' For 16,
because 'A'+6 is 'G'. It doesn't care if the value is within hexadecimal range
or not (numbers bigger than 15 can't be turned into one hex digit, they need
more digits). But here it's OK, because the routine is local to WordtoHex that
will never pass anything else than 0 to 15.
> begin
> HexStr := ' ';
Logical error: You must initalize HexStr to an empty String, '', if not it will
consist of a space and three hex digits, not four. A hex-Word String is
Composed of four hexadeciamal-digits. Because you have declared the String as a
Variable of the Type St4 and St4 only allows four Chars, exactly what is needed
For a hexWord-String, the last one added will be discarded if you have a space
at the beginning, filling up one position.
> HexStr := HexStr + Translate(Hi(W) shr 4);
> HexStr := HexStr + Translate(Hi(W) and 15);
> HexStr := HexStr + Translate(Lo(W) shr 4);
> HexStr := HexStr + Translate(Lo(W) and 15);
> WordtoHex := HexStr;
> end;
It would be easier to read if the 'and'-value were in hex-notation, $000F. See
below For explanation why. However, this part requires some understanding of
the bits. It's probably best show With an example. Let's say, our number W is
$1234.
$1234 is written 0001 0010 0011 0100 in binary. Each hex-digit corresponds to a
four-group binary digits.
þ) The binary number 0001 is 0*(2^3) + 0*(2^2) + 0*(2^1) + 1*(2^0). It gives
0+0+0+1=1 in decimal.
þ) The binary number 0101 is 0*(2^3) + 1*(2^2) + 0*(2^1) + 1*(2^0). It gives
0+4+0+1=5 in decimal.
þ The _decimal_ number 1101 is 1*(10^3) + 1*(10^2) + 0*(10^1) + 1*(10^0). It
gives 1000+100+0+1=1011! As you can see, the only difference between the
decimal and the binary and the hexadecimal system is the base-power. True, the
hex-system Uses strange digits For us used to decimal, but For the ones used to
binary, 2-9 is equally strange...
Like our decimal system, in hex and binary, it's unnescessary to include
leading zeros, i. e. $0001 = $1 (of course you can't remove trailing zeroes,
decimal 1000 certainly isn't equal to decimal 1...). But you will note that I
sometimes include these leading zeroes, just because it looks good (?). and
writing binary number 1000 0000 is like writing 10000 in decimal as 10,000;
it's only For easy reading, but the Compiler won't allow it.
However, I hope you grasp a least something of my extremly bad explanation :-(,
or maybe you know it beFore?! Now, let's look at the things that happens when
the above statements are executed and w = $1234 (0001 0010 0011 0100).
Hi returns the upper 8 bits of the Word, in this Case 0001 0010; Lo returns the
lower bits (!), 0011 0100. The above code Uses 'and' and 'shr', a breif
explanation of them will probably be nescessary (oh no :-)).
þ and, when not used as a Boolean operator, Uses two binary numbers and, For
each bit, tests them. if _both_ bits are set (equal to 1) the resuling bit is
set to 1, if any or both of them is cleared (equal to 0) the result is 0. This
means:
0001 0010 Hi(w) 0011 0100 Lo(w)
0000 1111 and With 15 or $000F 0000 1111 and With 15 or $000F
--------- ---------
0000 0010 0010 binary = 2 hex 0000 0100 0100 binary = 4 hex
This was the second and first statement, and out you get the second and first
number! When we pass them to Translate, we get back '2' and '4'.
þ shr, only For binary operations, shifts the bits to the right. The bits that
passes over the right side is lost, and the ones that move on left side is
replaced by zeroes. The bits shifts as many times as the value after the
shr-keyWord, here 4 times. Like this:
00010010 Hi(w) 00110100 Lo(w)
-------- shr 4 --------
00001001 after one shift 00011010
00000100 after two shifts 00001101
00000010 after three shifts 00000110
00000001 after four shifts 00000011
Now we got binary 0001 and binary 0011, in hex $1 and $3. The first and third
statement, and the first and third number! The String to return is digit1 +
digit2 + digit3 + digit4, exactly what we want.
Hmm... Now I haven't told you anything about the binary or, xor, not and
shl-keyWords... But I think this message is quiet long as it is, without that.
But if you want more info or a better explanation, only drop me a msg here.
Happy hacking /Jake 930225 17.35 (started writing last night)
PS. There may be some errors, I haven't proof-read the Text or my math. then,
please correct me, anybody.
}
[Back to NUMBERS SWAG index] [Back to Main SWAG index] [Original]