2013-05-12 33 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. 
相關問題