使用delphi代码将20位十进制值转换为十六进制

时间:2011-06-23 16:49:22

标签: delphi

我正在尝试使用Delphi代码将20位十进制值转换为十六进制。虽然我在C#中找到了下面的代码。

BigInteger bi = new BigInteger("12345678901234567890"); 
string s = bi.ToHexString();

任何人都可以帮助使用等效的delphi代码来实现这个目标吗?

请注意,使用kstools代码,我能够将17位十六进制值转换为20位小数,但我无法将其反转以获取十六进制值。

kstool代码如下:

var 
  I: TksInteger;
....
I.FromString('$ABDCF123456789FE');
Result = I.AsString;

4 个答案:

答案 0 :(得分:6)

这是一个C#answer to an identical question的Delphi翻译:

program DecToHex;

{$APPTYPE CONSOLE}

uses
  SysUtils, Generics.Collections;

function DecimalToHex(const Dec: string): string;
var
  bytes: Generics.Collections.TList<Byte>;
  i, digit, val: Integer;
  b: Byte;
  c: Char;
begin
  bytes := Generics.Collections.TList<Byte>.Create;
  try
    bytes.Add(0);
    for c in Dec do
    begin
      Assert(CharInSet(c, ['0'..'9']));
      val := ord(c)-ord('0');
      for i := 0 to bytes.Count-1 do
      begin
        digit := bytes[i]*10 + val;
        bytes[i] := digit and $0F;
        val := digit shr 4;
      end;
      if (val<>0) then
        bytes.Add(val);
    end;

    Result := '';
    for b in bytes do
      Result := '0123456789ABCDEF'[b+1] + Result;
  finally
    bytes.Free;
  end;
end;

const
  test = '56493153725735501823';

begin
  WriteLn(test + ' = $' + DecimalToHex(test));
end.

输出:

56493153725735501823 = $30FFFFFFFFFFFFFFF

答案 1 :(得分:3)

究竟是什么问题?

使用您提供的示例,它只适用于此。

<强>证明

此代码将12345678901234567890转换为字符串,然后返回到数字。

program Project122; {$APPTYPE CONSOLE}

uses SysUtils;

const SomeBigNumber=12345678901234567890;
var S:String; SomeBigNumber2:UInt64;

begin
  WriteLn(SomeBigNumber);
  S := '$'+IntToHex(SomeBigNumber, 40);
  Writeln('As Hex: ',S);
  Writeln;
  Writeln('Now let''s convert it back...');
  SomeBigNumber2 := StrToInt64(S);
  Writeln(SomeBigNumber2);
  ReadLn;
end.

<强>输出:

12345678901234567890 As Hex:
$AB54A98CEB1F0AD2

Now let's convert it back...
12345678901234567890

如果您要转换任何 20位数字,这将无效,因为最大的数字不适合UINT64。

18446744073709551615 is the largest number that you can fit in a UIN64. 
12345678901234567890

答案 2 :(得分:1)

与David Heffernan翻译相同,但优化并兼容旧的Delphi版本......

function DecimalToHex(const Dec: AnsiString): AnsiString;
var
  ResultArray: array of byte;
  n, i: Integer;
  val, digit: Byte;
  c: AnsiChar;
begin
  SetLength(ResultArray, Trunc(Length(Dec) * Ln(10) / Ln(16)) + 1);
  n := 0;
  for c in Dec do
  begin
    Assert(CharInSet(c, ['0'..'9']));
    val := ord(c) - ord('0');
    for i := 0 to n  do
    begin
      digit := ResultArray[i] * 10 + val;
      ResultArray[i] := digit and $0F;
      val := digit shr 4;
    end;
    if val <> 0 then
    begin
      inc(n);
      ResultArray[n] := val;
    end;
  end;
  Result := '';
  for digit in ResultArray  do
    Result := AnsiString('0123456789ABCDEF')[digit + 1] + Result;
end;

答案 3 :(得分:1)

以下Delphi函数转换十进制数并返回右对齐的十六进制数。它不优雅,但它有效。

//Uses STRUTILS Delphi module
function IHEX(x:Double): string; //Returns hex number as right-justified string
var i,k,a,mx:Integer;
y,Z,a1:currency;
 s:string;
 hxs: array[0..15] of string;
const hx='0123456789ABCDEF';
begin


Y:=abs(X);    //Make sure target decimal is not a negative number
mx:=0;    //Count number of hex digits derived from conversion

repeat
z:= y / 16;   // Divide the decimal number by base 16
a:=Trunc(z);  // Get integer part of dividend
if z>=16 then  begin  //If integer dividend greater than 16
    a1:=16 * Frac(z);//Get the dividend carry-over
    k:=Trunc(a1);    // Base 16 left-to-right placement digit
    If k<=9 then hxs[mx]:=IntToStr(k) //if hex digit greater than 9,
       else
        hxs[mx]:=hx[k+1];        //get hex alpha digit
    mx:=mx+1;           //increment hex digit placement
    y:=a;               //Replace decimal with current dividend result
end;
if z<16 then begin          //When dividend less than 16,
   a1:=16 * Frac(z);        //get dividend carry-over
    k:=Trunc(a1);           //Base 16 left-to-right placement digit
    If k<=9 then hxs[mx]:=IntToStr(k) //If hex digit greater than 9,
       else
        hxs[mx]:=hx[k+1];        //get hex alpha digit
    mx:=mx+1;            //increment hex digit placement
    y:=a;                //Replace decimal with current dividend result
end;
until y<16;             //When loop ends, last hex digit derived from division

If a<=9 then hxs[mx]:=IntToStr(a)  //If last hex digit greater than 9,
       else
        hxs[mx]:=hx[a+1];       //get hex alpha digit
//Pull HEX digits from placement array in reverse order to create HEX number
 s:='';
 i:=mx;
   repeat
     s:=s + hxs[i];
     i:=i-1;
   until i<0;
   s:=s+'H';
 //Format HEX number as seven characters RIGHT-JUSTIFIED
  repeat
   k:=Length(s);
     if k<7 then s:='0'+s;
   until Length(s)>=7;
Result:=s;
end;