如何声明Int64常量?

Ian*_*oyd 5 delphi constants delphi-7 delphi-5 int64

我试图在Delphi中定义一个常量:

const
   FNV_offset_basis = 14695981039346656037;
Run Code Online (Sandbox Code Playgroud)

我得到错误:整数常数太大

注意: 14,695,981,039,346,656,037十进制等于0x14650FB0739D0383十六进制.

我怎样才能宣布这个Int64常数?

我尝试过的其他一些事情:

const
   FNV_offset_basis: Int64 = 14695981039346656037;
   FNV_offset_basis = Int64(14695981039346656037);
   FNV_offset_basis: Int64 = Int64(14695981039346656037);


var
   offset: LARGE_INTEGER;
begin
   //recalculate constant every function call
   offset.LowPart = $739D0383;
   offset.HighPart = $14650FB0;
Run Code Online (Sandbox Code Playgroud)

更正

我的基本假设是错误的.

粘贴14695981039346656037到Windows 7计算器,并转换为十六进制,使我相信,hex等值的146959810393466560370x14650FB0739D0383:

在此输入图像描述

那是不对的.

因此,当我看到一个16位十六进制值,未设置高位时,我认为它可以适合64位有符号整数.

实际上,十六进制等价物14695981039346656037是......别的东西.罗布,你是对的!(大概)

Dav*_*nan 11

您在问题中的十六进制转换不正确.该数字实际上是$ cbf29ce484222000,并且不适合带符号的64位整数.您需要一个无符号的64位整数来表示它.Delphi 5中没有未签名的UInt64,所以你运气不好.没有可以在您的Delphi版本中表示该数字的整数数据类型.

如果满足您的需要,您可以将位模式解释为带符号值.在这种情况下,你会有一个负数.


Jon*_*eet 5

该数字大于有符号的64位整数可以容纳的数字.你试过用过UInt64吗?

  • Delphi 5(1999)和7(2002)都有`Int64`,但都没有`UInt64`.然而,现代德尔福版本确实如此.:) (2认同)

Ian*_*oyd 5

我只需要64位变量来保存64位(无符号)数字.我仍然可以使用Delphi Int64来完成它,但诀窍是如何声明我需要的常量:

const
    FNV_offset_basis: ULARGE_INTEGER = (LowPart: $cbf29ce4; HighPart: $84222000);
Run Code Online (Sandbox Code Playgroud)

(感谢Dave和Rob找到正确的十六进制值)

虽然我是严格来说,不使用Int64,我正在使用Int64:

var
   hash: Int64;
begin
   hash := FNV_offset_basis.QuadPart;

   for i := 1 to Length(s) do
   begin
       hash := hash xor Byte(s[i]);
       hash := UInt64Mul(hash, 1099511628211);       
   end;

   Result := UInt64mod(hash, map.Length);
end;
Run Code Online (Sandbox Code Playgroud)

有一些精心设计的UInt64Xxx数学例程:

function UInt64mod(const Dividend: Int64; const Divisor: DWORD): DWORD;
var
    d2: LongWord;
    remainder: LongWord;
begin
    //Upper half of dividend cannot be larger than divisior, or else a #de divide error occurs
    //Keep multiplying by two until it's larger.
    //We fixup at the end
    d2 := Divisor;
    while d2 < u.HighPart do
       d2 := d2 * 2;

    asm
        MOV   EDX, ULARGE_INTEGER(Dividend).HighPart;
        MOV   EAX, ULARGE_INTEGER(Dividend).LowPart;
        MOV   ECX, d2;

        //EAX := EDX:EAX / r/m32, EDX=remainder
        DIV   ECX;
        MOV   remainder,EDX
    end;

    //Fixup for using larger divisor
    Result := remainder mod Divisor;
end;
Run Code Online (Sandbox Code Playgroud)

我会将实施UInt64Mul作为练习留给读者.