Reputation: 256591
i'm trying to define a constant in Delphi:
const
FNV_offset_basis = 14695981039346656037;
And i get the error: Integer constant too large
Note:
14,695,981,039,346,656,037
decimal is equal to0x14650FB0739D0383
hex.
How can i declare this Int64
constant?
Some other things i've tried:
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;
Correction
My fundamental assumption was wrong.
Pasting 14695981039346656037
into Windows 7 Calculator, and converting to hex, led me to believe that the hex equivalent of 14695981039346656037
is 0x14650FB0739D0383
:
That is incorrect.
So when i saw a 16-digit hex value, with the high bit not set, i presumed it could fit in a 64-bit signed integer.
In reality the hex equivalent of 14695981039346656037
is...something else. Rob, you were right! (probably)
Upvotes: 5
Views: 5684
Reputation: 1
I had a WMI call that returned a Variant of type Uint64 not supported by Delphi 5. By assuming that Int64 was fair enough for the result I was expecting, 1- I Typecasted and stored the returned Variant into an Extended (Real Type), 2- I used the "Trunc" function that returns an Int64 from an Extended when needed.
Not exactly what you want but considering Real Types might help someone to achieve some "impossible" Delphi 5 math.
Upvotes: 0
Reputation: 1
The Windows 7 Calculator is faulty and strips the last Digit without warning also the Calculator seems not able to really calculate in 64Bits even if QWord is selected. It seems to be a Int64 Calculator only in Windows 7 and it also can't display enough Digits and simply strips them to a totally wrong Value. Interestingly the Windows XP Calculator does not have this Bug.
And the real Hex Value of 14695981039346656037 is 0xCBF29CE484222325 also 14695981039346656037 = (20921 * 465383 * 1509404459) now as a proof try to calculate it with this Calculator and you will get -3750763034362895579 (signed) instead of 14695981039346656037 (unsigned) in Programmer Mode, but it will be correct in Scientific Mode.
Upvotes: -1
Reputation: 256591
i only needed the 64-bit variable to hold a 64-bit (unsigned) number. i can still use Delphi's Int64
to accomplish it, but the trick was how to declare my needed constants:
const
FNV_offset_basis: ULARGE_INTEGER = (LowPart: $cbf29ce4; HighPart: $84222000);
(thanks for Dave and Rob for finding me the correct hex value)
While i am, strictly speaking, not using the Int64
, i am using an 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;
With some carefully crafted UInt64Xxx
math routines:
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;
i'll leave the implementation UInt64Mul
as an exercise for the reader.
Upvotes: 5
Reputation: 612814
Your hex conversion in the question is incorrect. That number is actually $cbf29ce484222000 and does not fit into a signed 64 bit integer. You would need an unsigned 64 bit integer to represent it. There is no unsigned UInt64 in Delphi 5 and so you are out of luck. There is no integral data type that can represent that number in your version of Delphi.
You could perhaps interpret the bit pattern as a signed value if that does what you need. In that case you would have a negative number.
Upvotes: 11
Reputation: 1499860
That number is bigger than a signed 64-bit integer can hold. Have you tried using UInt64
instead?
Upvotes: 5