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等值的14695981039346656037是0x14650FB0739D0383:

那是不对的.
因此,当我看到一个16位十六进制值,未设置高位时,我认为它可以适合64位有符号整数.
实际上,十六进制等价物14695981039346656037是......别的东西.罗布,你是对的!(大概)
Dav*_*nan 11
您在问题中的十六进制转换不正确.该数字实际上是$ cbf29ce484222000,并且不适合带符号的64位整数.您需要一个无符号的64位整数来表示它.Delphi 5中没有未签名的UInt64,所以你运气不好.没有可以在您的Delphi版本中表示该数字的整数数据类型.
如果满足您的需要,您可以将位模式解释为带符号值.在这种情况下,你会有一个负数.
该数字大于有符号的64位整数可以容纳的数字.你试过用过UInt64吗?
我只需要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作为练习留给读者.
| 归档时间: |
|
| 查看次数: |
3938 次 |
| 最近记录: |