Delphi 如何声明Int64常量?
我试图在Delphi中定义一个常量:Delphi 如何声明Int64常量?,delphi,constants,delphi-7,delphi-5,int64,Delphi,Constants,Delphi 7,Delphi 5,Int64,我试图在Delphi中定义一个常量: const FNV_offset_basis = 14695981039346656037; 我得到一个错误:整数常量太大 注意:14695981039346656037decimal等于0x14650FB0739D0383hex 如何声明此Int64常量 我还尝试了其他一些事情: const FNV_offset_basis: Int64 = 14695981039346656037; FNV_offset_basis = Int64(
const
FNV_offset_basis = 14695981039346656037;
我得到一个错误:整数常量太大
注意:14695981039346656037
decimal等于0x14650FB0739D0383
hex
如何声明此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
:
这是不正确的
所以,当我看到一个16位的十六进制值,并且没有设置高位时,我认为它可以适合64位有符号整数
实际上,
14695981039346656037
的十六进制等价物是……其他东西。罗布,你说得对!(可能)该数字大于有符号64位整数的容量。您是否尝试过改用UInt64
?问题中的十六进制转换不正确。这个数字实际上是$cbf29ce484222000,不适合有符号64位整数。您需要一个无符号的64位整数来表示它。Delphi 5中没有未签名的UInt64,因此您运气不佳。在您的Delphi版本中,没有可以表示该数字的整型数据类型
如果需要的话,可以将位模式解释为有符号值。在这种情况下,您将得到一个负数。我只需要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;
函数UInt64mod(常数被除数:Int64;常数除数:DWORD):DWORD;
变量
d2:长单词;
余数:长字;
开始
//红利的上半部分不能大于除数,否则会出现除数错误
//继续乘以2,直到它变大。
//我们在最后决定
d2:=除数;
而d2
我将把实现
UInt64Mul
留给读者作为练习。Windows 7计算器出现故障,并在没有警告的情况下删除最后一位数字。即使选择了QWord,计算器似乎也无法真正以64位进行计算。它似乎是一个仅在Windows7中使用的Int64计算器,而且它也不能显示足够的数字,只是简单地将它们分割成一个完全错误的值。有趣的是,WindowsXP计算器没有这个Bug
14695981039346656037的实际十六进制值是0xCBF29CE484222325,也就是14695981039346656037=(20921*465383*1509404459),现在作为证明,尝试使用此计算器计算它,在程序员模式下,您将得到-3750763034362895579(有符号)而不是146959810346656037(无符号),但它在科学模式下是正确的。我有一个WMI调用,返回了Delphi 5不支持的Uint64类型的变体。 假设Int64对于我所期望的结果来说足够公平, 1-我键入并将返回的变量存储到扩展(实型)中, 2-我使用了“Trunc”函数,该函数在需要时从扩展数据库返回Int64
不完全是你想要的,但考虑真实类型可能有助于某人实现一些“不可能的”Delphi 5数学。你是否尝试过:
FNV\u offset\u basis=$14650FB0739D0383代码>记录的可能重复:“FNV_offset_basis=14695981039346656037”在Delphi XE2中工作。@RRUZ这个问题是关于无符号64位整数的。这是关于Delphi及其有符号64位整数的。在这个帖子中,一个简单的回答是“买一个新版本的Delphi”(谢谢)@RobKennedy也删除了我的:)这个数字是有符号的,并且符合,符合,符合,符合Int64。它不符合。是CBF29CE484222000您是对的。基本上,我只需要将64位存储在一个64位变量中,其长度足以对其执行mod
操作(但基本上)。假设$cbf29ce484222000是有符号64位整数时,的十进制值是多少?-$340D631B7BDEDE000或-3750763034362896384此答案有问题吗?或者Jon's?Delphi 5(1999)和7(2002)都有Int64
,但都没有UInt64
。但是,现代的Delphi版本确实如此。:)@阿蒙,你应该努力合并你的账户。请使用