如何声明Int64常量?

时间:2012-04-24 17:26:09

标签: delphi constants delphi-7 delphi-5 int64

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

const
   FNV_offset_basis = 14695981039346656037;

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

  

注意: 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;

校正

我的基本假设是错误的。

14695981039346656037粘贴到Windows 7计算器中,并转换为十六进制,让我相信14695981039346656037的十六进制等值为0x14650FB0739D0383

enter image description here

这是不正确的。

因此,当我看到16位十六进制值,高位未设置时,我认为它可以适合64位签名整数。

实际上,14695981039346656037的十六进制等价物是......其他的东西。罗布,你是对的! (可能)

5 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:5)

该数字大于有符号的64位整数可以容纳的数字。您是否尝试过使用UInt64

答案 2 :(得分:5)

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

const
    FNV_offset_basis: ULARGE_INTEGER = (LowPart: $cbf29ce4; HighPart: $84222000);

(感谢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;

使用一些精心设计的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;

我会将实施UInt64Mul作为读者的练习。

答案 3 :(得分:0)

我有一个WMI调用返回了Delphi 5不支持的Uint64类型的Variant。 通过假设Int64对我期望的结果足够公平, 1- I Typecasted并将返回的Variant存储到扩展(Real Type)中, 2-我使用了“Trunc”函数,在需要时从Extended返回Int64。

不完全是你想要的,但考虑真实类型可能会帮助某人实现一些“不可能”的Delphi 5数学。

答案 4 :(得分:-1)

Windows 7计算器出现故障并在没有警告的情况下剥离最后一个数字,即使选择了QWord,计算器也似乎无法真正计算出64位数。它似乎只是在Windows 7中的Int64计算器,它也无法显示足够的数字并简单地将它们剥离为完全错误的值。有趣的是,Windows XP计算器没有此Bug。

真正的十六进制值14695981039346656037是0xCBF29CE484222325也14695981039346656037 =(20921 * 465383 * 1509404459)现在作为证明尝试用这个计算器计算它你将得到-3750763034362895579(签名)而不是程序员中的14695981039346656037(无符号)模式,但在科学模式下是正确的。