2012-04-24 22 views
5

próbuję definiować stałe w Delphi:Jak zadeklarować stałą Int64?

const 
    FNV_offset_basis = 14695981039346656037; 

i pojawia się błąd: Integer stały zbyt duży

Note:14,695,981,039,346,656,037 decimal is equal to 0x14650FB0739D0383 hex.

Jak mogę zadeklarować ten Int64 stałej?

kilka innych rzeczy Próbowałem:

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; 

Korekta

Moim podstawowym założeniem było źle.

wklejanie 14695981039346656037 do Windows 7 Kalkulator i konwersji na hex, doprowadziły mnie do przekonania, że ​​ekwiwalent szesnastkowy 14695981039346656037 jest 0x14650FB0739D0383:

enter image description here

który jest nieprawidłowy. kiedy

Więc ja zobaczyłem 16-cyfrowy wartość hex, z wysokim kawałka nie ustawić, ja domniemywać mogło zmieścić się w 64-bitowym podpisał całkowitą.

W rzeczywistości heksadecymalny odpowiednik 14695981039346656037 to ... coś innego. Rob, miałeś rację! (prawdopodobnie)

+0

Czy próbowałeś: 'FNV_offset_basis = $ 14650FB0739D0383;' –

+0

możliwy duplikat [Jak zdefiniować niepodpisaną 64-bitową liczbę całkowitą w Delphi7?] (Http://stackoverflow.com/questions/6378107/how-to-define -an-unsigned-64-bit-integer-in-delphi7) – RRUZ

+1

Dla zapisu: "FNV_offset_basis = 14695981039346656037" działa w Delphi XE2. – Giel

Odpowiedz

11

Twoja konwersja heksadecymalna w pytaniu jest niepoprawna. Ta liczba to faktycznie $ cbf29ce484222000 i nie pasuje do podpisanej 64-bitowej liczby całkowitej. Do reprezentowania potrzebowałbyś 64-bitowej liczby całkowitej bez znaku. W Delphi 5 nie ma niepodpisanego UInt64, więc nie masz szczęścia. Nie ma żadnego integralnego typu danych, który mógłby reprezentować tę liczbę w twojej wersji Delphi.

Być może można by zinterpretować wzór bitowy jako wartość oznaczoną, jeśli spełnia to, czego potrzebujesz. W takim przypadku będziesz miał liczbę ujemną.

+0

Numer jest podpisany i pasuje, podpisany, do Int64. –

+0

To nie pasuje. To jest cbf29ce484222000 –

+0

Masz rację. Zasadniczo wystarczy tylko przechowywać 64-bitowe zmienne 64-bitowe wystarczająco długo, aby wykonać na nim operację 'mod' (ale zasadniczo). Jaka jest dziesiętna wartość '$ cbf29ce484222000' przy założeniu, że jest to 64-bitowa * podpisana * liczba całkowita? –

5

Ta liczba jest większa niż liczba 64-bitowa, którą można zapisać. Czy próbowałeś już użyć UInt64?

+2

Delphi 5 (1999) i 7 (2002) oba mają "Int64", ale nie ma też "UInt64". Jednak nowoczesne wersje Delphi. :) –

5

Potrzebowałem tylko 64-bitowej zmiennej do przechowywania 64-bitowej (bez znaku) liczby. mogę nadal używać Delphi Int64 do osiągnięcia, ale sztuczka była jak deklarować swoje potrzebne stałe:

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

(podziękowania dla Dave i Rob za znalezienie mi poprawną wartość hex)

a ja am, ściśle mówiąc, nie używając Int64, używam 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; 

w niektórych starannie spreparowane UInt64Xxx procedur matematycznych:

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; 

Zostawię wykonanie UInt64Mul jako ćwiczenie dla czytelnika.

-1

Kalkulator Windows 7 jest uszkodzony i usuwa ostatnią cyfrę bez ostrzeżenia, a kalkulator nie jest w stanie obliczyć w 64 bitach, nawet jeśli wybrano QWord. Wydaje się, że jest to Kalkulator Int64 tylko w Windows 7 i nie może wyświetlać wystarczającej liczby Cyfrów i po prostu usuwa je do całkowicie niewłaściwej Wartości. Co ciekawe, kalkulator systemu Windows XP nie ma tego błędu.

a prawdziwa Hex Wartość 14695981039346656037 jest 0xCBF29CE484222325 również 14695981039346656037 = (20921 * 465383 * 1509404459) teraz jako dowód spróbować go obliczyć z tego kalkulatora, a dostaniesz -3750763034362895579 (podpisany) zamiast 14695981039346656037 (unsigned) w Tryb programisty, ale będzie prawidłowy w trybie naukowym.

+0

@Amenom powinieneś dążyć do scalenia swoich kont. Proszę skorzystać z [formularza kontaktowego] (http://stackoverflow.com/contact) – Vogel612

0

miałem rozmowę WMI że zwracany wariant typu Uint64 nie obsługiwanego przez Delphi 5. Przy założeniu, że Int64 było mało sprawiedliwy dla wyniku spodziewałem, 1- I Typecasted i przechowywane wracającą wariantowego na powiększonym (Real Type), 2- Użyłem funkcji "Trunc", która zwraca Int64 z Extended, gdy jest to konieczne.

Nie dokładnie to, co chcesz, ale biorąc pod uwagę prawdziwe typy, może pomóc komuś osiągnąć "niemożliwą" matematykę Delphi 5.