4

这是我用来从数字数组和基值生成 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 值,如何为给定的基值(其中基值> 1)生成 ADigits 数组?

2) 如何确定表示给定 UInt64 值的给定基值(其中基值 > 1)的 ADigits 数组的长度?

4

2 回答 2

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;
于 2013-05-12T21:31:43.887 回答
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.
于 2013-05-12T20:49:13.673 回答