Here's a function that works somewhat like the C runtime library's itoa
function, converting a positive integer value (Cardinal
in Delphi) to a specified radix between 2 and 36. It's been tested under Delphi 2007 and XE4.
type
TRadixRange = 2..36;
function ConvertIntToBase(value : Cardinal; Radix : TRadixRange) : string;
const
Digits: array[0..35] of Char = ('0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z');
var
nIndex : Integer;
begin
Result := '';
repeat
nIndex := value mod radix;
Result := Digits[nIndex] + Result;
Value := Value div radix;
until Value = 0;
end;
Just for fun, I decided to write a function to "undo" the conversion (convert from another radix back to decimal (base 10)). It's also modeled (very loosely) after the C RTL function atoi
, except it requires you to pass in the radix of the number being passed.
function ConvertBaseToInt(const Value: string; const Radix: TRadixRange): Cardinal;
var
i: Integer;
Increment: Byte;
begin
Result := 0;
for i := 1 to Length(Value) do
begin
case Value[i] of
'0'..'9': Increment := Ord(Value[i]) - Ord('0');
'A'..'Z',
'a'..'z': Increment := Ord(Value[i]) - Ord('A') + 10;
else
Increment := 0;
end;
end;
Result := Result * Radix + Increment;
end;
Note that ConvertIntToBase
was tested with many numeric inputs, but I can only validate those bases supported by Windows Calculator in programmer mode (binary (base 2), octal (base 8), decimal (base 10, which I did not test), and hex (base 16)), as I don't have a calculator that will support other radix values and didn't want to do the work by hand. ;-)
ConvertBaseToInt
was tested by passing in the test values of ConvertIntToBase
and confirming that what went into one was what came back out of the other; IOW, that a number converted into binary by ConvertIntToBase
would result in the same number when run back through ConvertBaseToInt
.
You can test it with something similar to this in a console application:
var
TempStr: string;
Reversed: Integer;
i: Integer;
Base: Byte;
const
FmtStr = 'Value (base %d): %d %s and back %d';
begin
for i := 0 to 16 do
begin
for Base in [2, 8, 16] do
begin
// Test bin, oct, and hex for a range of values from 0..65536
TempStr := ConvertIntToBase(1 shl i, Base);
Reversed := ConvertBaseToInt(TempStr, Base);
Writeln(Format(FmtStr, [Base, 1 shl i, TempStr, Reversed]));
end;
end;
Readln;
end.