这是我用来从数字数组和基值生成UInt64结果的函数。
function BaseNToInteger(const ABase: Cardinal; const ADigits: Array of Byte): UInt64;
var
i: Integer;
begin
Result := 0;
for i := 0 to (Length(ADigits) - 1) do begin
Result := Result + (ADigits[i] * Power(i, ABase));
end;
end;
[请不要担心那里的Power()功能;我编写了自己的,使用红衣主教并生成UInt64结果。]
这很容易。
由于我的数学技能多年来似乎已经生锈,我正在努力解决的难点是:
1)对于给定的UInt64值,如何为给定的基值(其中base> 1)生成ADigits数组?
2)如何确定代表给定UInt64值的给定基值(其中base> 1)的ADigits数组的长度?
答案 0 :(得分:4)
作为动态数组的函数实现......
uses math;
type
TDigits = Array of Byte;
Function BaseNToInteger(const Digits: TDigits; Base: Integer): Cardinal;
var
i: integer;
begin
Result := 0;
for i := High(Digits) DownTo Low(Digits) do
Result := Base * Result + Digits[i];
end;
Function IntegerToBaseN(Nr: Cardinal; Base: Integer): TDigits;
var
i: integer;
function CeilAllways(const X: Extended): Integer;
begin
Result := Integer(Trunc(X));
if Frac(X) >= 0 then
Inc(Result);
end;
begin
SetLength(Result, CeilAllways(ln(Nr) / ln(Base)));
for i := Low(Result) to High(Result) do
begin
Result[i] := Nr mod Base;
Nr := Nr div Base;
end;
end;
答案 1 :(得分:3)
根据我之前的评论,这是一种可能性(编译但未经过测试)
unit BaseConv;
interface
type
TDigits = array[0 .. 63] of uint32;
{ Recover number from digits, number of digits is in nd }
procedure ToInteger(var n: uint32; var digits: TDigits; nd, base: integer);
{ Compute digits in given base, number of digits is returned in nd }
procedure FromInteger(n: uint32; var digits: TDigits; var nd: integer; base: integer);
implementation
procedure ToInteger(var n: uint32; var digits: TDigits; nd, base: integer);
var i: integer;
begin
n := 0;
for i := nd - 1 downto 0 do n := base*n + digits[i];
end;
procedure FromInteger(n: uint32; var digits: TDigits; var nd: integer; base: integer);
begin
nd := 0;
repeat
digits[nd] := n mod base;
n := n div base;
nd := nd + 1;
until n = 0;
end;
end.