2013-05-12 30 views
4

以下是我用来从数字和基数值数组中生成UInt64结果的函数。给定值的基数n数字

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值,我怎么产生ADigits阵列对于给定基值(基数> 1)?

2)如何确定ADigits数组对于给定基值(基数> 1)的长度,它将表示给定的UInt64值?

+0

如果循环不需要电源以相反的顺序(你只会相乘)。对于反向操作(整数到基数n),您将重复除以基数(其余为连续数字)。最大长度由ceiling(log(2^64-1)/ log(base))给出。最简单的方法是一次性修复最大可能长度,即64(基数为2)。 – 2013-05-12 20:36:32

回答

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; 
+0

最优雅。谢谢。 – Adem 2013-05-12 22:15:04

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. 
相关问题