Title: How to convert between binary, octal, decimal and hexadecimal
unit NumSystems;
// *****************************************************
// * *
// * 2007 by Derek van Daal *
// * derek_vdaal at gmx dot net *
// * *
// * Features: *
// * - Convert int bin oct dec hex *
// * - Full 32 bit support (up to FFFFFFFFh) *
// * - Three functions: *
// * 1. StrToNumInt *
// * 2. IntToStrNum *
// * 3. ConvertNum *
// * *
// * ---===Use and abuse at your own risk===--- *
// * *
// *****************************************************
interface
uses
SysUtils;
type
//Different numbering system enumeration
TNumSys = (nsBin, nsOct, nsDec, nsHex);
const
//Extended characters to represent hex numbering system
DigitList = '0123456789ABCDEF';
////////////////////////////////////////////////////////////////////////////////
//Convert a number in string representation of a numbering sys to integer
function StrNumToInt(const Value: String; const InNumSys: TNumSys): Cardinal;
//Convert an integer to a string representation of another numbering sys
function IntToStrNum(Value: Cardinal; const OutNumSys: TNumSys;
Digits: Integer): String;
//Convert two string representations of numbers two different numbering sys
function ConvertNum(const Value: String; const InNumSys, OutNumSys: TNumSys;
Digits: Integer): String;
////////////////////////////////////////////////////////////////////////////////
implementation
//******************************************************************************
{
Returns the numerical value of the input numbering system
@param NumSys the numbering system
@result the base of the numbering system
}
{$WARNINGS OFF}
function GetBase(const NumSys: TNumSys): Integer;
begin
case NumSys of
nsBin: Result := 2;
nsOct: Result := 8;
nsDec: Result := 10;
nsHex: Result := 16;
end;
end;
{$WARNINGS ON}
//******************************************************************************
{
Checks whether a digit representing a number is valid according to its base.
@param Digit the digit to check
@param Base the base of the digit
@result the validity of the digit
}
{$WARNINGS OFF}
function DigitValid(Digit: Char; Base: Integer): Boolean;
begin
case Base of
2: Result := Digit in ['0'..'1'];
8: Result := Digit in ['0'..'7'];
10: Result := Digit in ['0'..'9'];
16: Result := Digit in ['0'..'9', 'A'..'F'];
end;
end;
{$WARNINGS ON}
//******************************************************************************
{
Returns the integer value of a digit in any numbering system.
@param Digit the digit representation to convert
@result the Integer value of the digit represented
}
function DigitToInt(Digit: Char): Integer;
begin
case Digit of
'0'..'9': Result := ord(Digit) - 48;
'A'..'Z': Result := ord(Digit) - 55;
else Result := -1;
end;
end;
//******************************************************************************
{
Returns Base^Exp of a positive Exp.
@param Base the base of the equation
@param Exp the exponent of the equation (must be = 0)
@result the answer of the power equation
}
function PowerInt(Base: Cardinal; const Exp: Cardinal): Cardinal;
var
k: Cardinal;
begin
//x^0 is always 1
if Exp = 0 then
begin
Result := 1;
Exit;
end;
Result := Base;
for k := 1 to Exp-1 do
Result := Result * Base
end;
//******************************************************************************
{
Adds leading '0' characters to a string
@param S the source string
@param Count the amount of '0's to add
@result The newly formatted string with leading '0's
}
function AddLeadingZeros(const S: String; Count: Integer): String;
var
k: Integer;
begin
Result := '';
for k := 1 to Count do
Result := Result + '0';
Result := Result + S;
end;
//******************************************************************************
{
Sets the minimum number of digits in a string. If Count the current length
of S then the result is filled by '0' character from the left.
@param S the source string
@param Count the length of the result string
@result the newly sized string
}
function SetDigitCount(const S: String; Count: Integer): String;
var
NewString: String;
begin
NewString := S;
if Length(S)
NewString := AddLeadingZeros(S, Count - Length(S));
Result := NewString;
end;
//******************************************************************************
{
Returns the decimal value of a digit in a numering system with base Base
at a specified digit position.
@param Digit the digit in the numbering system
@param Base the base of the numbering system of Digit
@param Index the index of the digit in the number representation
where 0 is the rightmost digit.
@result the decimal value returned
}
function DigitValue(Digit: Char; Index: Integer; Base: Integer): Cardinal;
var
IDigit: Cardinal;
begin
if not DigitValid(Digit, Base) then
raise EConvertError.Create
(Format('''%S'' is not a valid digit within a number of base %d',
[Digit, Base]));
//Need to have numerical value for digits (ie Ah = 10)
IDigit := DigitToInt(Digit);
//In decimal: 300 = 3 * 10^2
Result := IDigit * PowerInt(Base, Index);
end;
//******************************************************************************
{
Converts a string representation of a numerical value in a specified
numbering system to an integer value.
@param Value the string representation of a value
@param InNumSys the numbering system of Value
@result the integer value of the input numerical value
}
function StrNumToInt(const Value: String; const InNumSys: TNumSys): Cardinal;
var
k: Integer;
Base: Integer;
begin
Result := 0;
Base := GetBase(InNumSys);
//Add all the values of the sequential digits in the number text
//representation to Result
for k := Length(Value) downto 1 do
Result := Result + DigitValue(Value[k], Length(Value) - k, Base);
end;
//******************************************************************************
{
Converts an intger value to a string representation of a numerical value
in a specified numbering system.
@param Value the input integer value to convert
@param OutNumSys the output numbering system of the result
@param Digits the minimum number of digits for the result
@result the string representation of Value in a specified numbering system
}
function IntToStrNum(Value: Cardinal; const OutNumSys: TNumSys;
Digits: Integer): String;
var
Base: Cardinal;
begin
if Value = 0 then
begin
Result := SetDigitCount('0', Digits);
Exit;
end;
Result := '';
Base := GetBase(OutNumSys);
//Determine the digit character for every character position in the number
//text representation and add it to Result
while Value 0 do
begin
Result := DigitList[(Value mod Base) + 1] + Result;
Value := Value div Base;
end;
Result := SetDigitCount(Result, Digits);
end;
//******************************************************************************
{
Converts an a string representation of a numerical value in a specified
numbering system to a string representation of a numerical value in a
different numbering system.
@param Value the string representation of a number to convert
@param InNumSys the input numbering system of Value
@param OutNumSys the output numbering system of the result
@param Digits the minimum number of digits for the result
@result the string representation of Value in a specified numbering system
}
function ConvertNum(const Value: String; const InNumSys, OutNumSys: TNumSys;
Digits: Integer): String;
begin
Result := IntToStrNum(StrNumToInt(Value, InNumSys), OutNumSys, Digits);
end;
//******************************************************************************
end.