Reputation: 2291
Luckily, Delphi has an RTL function that converts a binary value into its hexadecimal representation, namely BinToHex(), declared in System.Classes
as follows:
1. procedure BinToHex(const Buffer: TBytes; BufOffset: Integer; var Text: TBytes; TextOffset: Integer; Count: Integer);
2. procedure BinToHex(Buffer: PAnsiChar; Text: PAnsiChar; BufSize: Integer);
3. procedure BinToHex(Buffer: PAnsiChar; Text: PWideChar; BufSize: Integer);
4. procedure BinToHex(var Buffer; Text: PWideChar; BufSize: Integer);
5. procedure BinToHex(var Buffer; Text: PAnsiChar; BufSize: Integer);
6. procedure BinToHex(Buffer: Pointer; Text: PWideChar; BufSize: Integer);
7. procedure BinToHex(Buffer: Pointer; Text: PAnsiChar; BufSize: Integer);
Delphi documentation states that the first parameter, i.e. Buffer
is a pointer to an array of bytes. That means the function expects binary number passed as an array of bytes. Thus, one of possible way to convert binary to hexadecimal is as follows:
procedure Test();
var
aBinNum : TBytes;
sHexNum : string;
iBinSize: Integer;
begin
aBinNum := TBytes.Create(255, 7); // An array of decimal numbers, right?
iBinSize := Length(aBinNum) * 2;
SetLength(sHexNum, iBinSize);
BinToHex(aBinNum, PWideChar(sHexNum), iBinSize);
WriteLn(sHexNum); // The output is FF07
end;
The problem with this approach is that the binary number must be written as decimal number because there is no such 0b11111111
0b0111
as in GCC, for example.
Since the definition of binary number is a number expressed in the base-2 numeral system, I expect BinToHex()
can receive a real base-2 number, maybe in form of string.
Is it possible to use the 3rd form of BinToHex()
so that I can pass a real base-2 number to the function?
If that is not possible, probably BinToHex()
should be renamed to DecToHex()
or BytesToHex()
. Just kidding. :-)
Upvotes: 2
Views: 1365
Reputation: 613302
BinToHex
is not intended to convert from a binary representation of an integer, as you are expecting. What it does is simply encode an array of bytes as hex. For instance. If you pass BinToHex
the following bytes:
1, 2, 255
then BinToHex
will encode that as:
0102ff
By binary what is meant is simply an array of bytes. It is not meant to indicate an integer represented in base 2.
You are looking for a function like this:
function Base2TextToInt(const Text: string): Cardinal;
var
Index: Integer;
Digit: Cardinal;
begin
Digit := 1;
Result := 0;
for Index := Length(Text) downto 1 do
begin
case Text[Index] of
'0':
; // do nothing
'1':
inc(Result, Digit);
else
raise EConvertError.CreateFmt('''%s'' is not a valid binary digit.', [Text[Index]]);
end;
Digit := Digit shl 1;
end;
end;
Note that I have ignored the error case of there being more than 32 digits. I'll leave that as an exercise to the reader.
One of the common misconceptions that people have is that a number can be a decimal number, or a binary number, and so on. Decimal, binary, etc. are just representations of a number. So, decimal 15
is equal to hex f
is equal to binary 1111
. These are all the same number, represented differently.
Now, on a computer, if you want to differentiate between representations of a number, you do so with text. When you write:
i := 15;
j := $f;
you have assigned the same value to i
and j
. You can write
Assert(i = j);
If you are looking to enter a binary representation of a number into your source code, you are out of luck. Delphi supports decimal and hexadecimal representations only.
If you wish to convert a number to its binary representation, or vice versa, you use a function like the one I gave above. That function converts from a binary representation, stored in a string, to a number.
Upvotes: 3