2012-04-24 33 views
5

私はDelphiで定数を定義しようとしている:Int64定数の宣言方法は?

const 
    FNV_offset_basis = 14695981039346656037; 

を、私はエラーを取得:整数定数が大きすぎ

Note:14,695,981,039,346,656,037 decimal is equal to 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; 

修正

を私の基本的な前提が間違っていました。

Windows 7の電卓に貼り付ける14695981039346656037、および進への変換、14695981039346656037の六角相当0x14650FB0739D0383であることを信じるように私を導いた:間違ってい

enter image description here

を。

だから、ときに私はに設定されていない高ビットで、16桁の16進値を見て、私はそれが64ビットに合うことができると推定符号付き整数。

実際には、14695981039346656037の16進数は...何か他のものです。ロブ、あなたは正しかった! (おそらく)

+0

は、あなたがしようとしたがいる: 'FNV_offset_basis = $ 14650FB0739D0383;の' –

+0

可能複製(http://stackoverflow.com/questions/6378107/how-to-define [Delphi7の符号なし64ビット整数を定義する方法?] -an-unsigned-64-bit-integer-delphi7) – RRUZ

+1

レコードの場合: "FNV_offset_basis = 14695981039346656037"はDelphi XE2で動作します。 – Giel

答えて

11

質問の16進数の変換が正しくありません。その数値は実際には$ cbf29ce484222000であり、符号付き64ビット整数には収まらない。それを表すには、符号なし64ビット整数が必要です。 Delphi 5には署名のないUInt64はありませんので、あなたは不運です。あなたのバージョンのDelphiでその数値を表すことができる整数データ型はありません。

ビットパターンが必要な場合は、ビットパターンを符号付きの値として解釈できます。その場合は、負の数になります。

+0

番号は署名され、Int64に署名、適合します。 –

+0

これは適合しません。それはcbf29ce484222000 –

+0

あなたは正しいです。基本的には、(基本的に) 'mod'演算を実行するのに十分な長さの64ビット変数に64ビットしか格納する必要がありません。 '$ cbf29ce484222000'の小数点は、* signed * 64ビットの整数であると仮定したときの小数はどうですか? –

5

この数は、符号付き64ビット整数より大きい値です。代わりにUInt64を使用してみましたか?

+2

Delphi 5(1999)および7(2002)はどちらもInt64を持っていますが、どちらもUInt64を持っていません。しかし、現代のDelphiのバージョンはそうです。 :) –

5

私は、64ビット(符号なし)の番号を保持するために64ビットの変数が必要でした。私はまだそれを達成するためにDelphiのInt64を使用することができますが、トリックは私に必要な定数を宣言する方法だった:

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

(私正しい進値を見つけるためのデイブとロブに感謝)

をしながら私は午前は、厳密にInt64を使用していない、言えば、私はInt64型を使用しています:いくつかの巧妙に作成されたUInt64Xxx数学ルーチンで

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; 

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を残しておきます。

-1

Windows 7電卓は故障しており、QWordが選択されていても電卓が実際に64Bitで計算できないように見えることがあります。それはWindows 7のInt64 Calculatorのようで、十分な数字を表示することができず、単にそれらを完全に間違った値に取り除くだけです。興味深いことに、Windows XPの電卓にはこのバグはありません。証拠として今

そして14695981039346656037の本当の16進値は0xCBF29CE484222325は14695981039346656037 =(* 465383 20921 * 1509404459)もあり、この電卓でそれを計算してみてください、あなたが代わりに14695981039346656037の-3750763034362895579(署名)(符号なし)を取得しますでプログラマーモードですが、科学的モードでは正しいでしょう。

+0

@Amenomあなたはあなたのアカウントをマージしようと努めるべきです。 [連絡フォーム](http://stackoverflow.com/contact)をご利用ください。 – Vogel612

0

私は型変換と拡張に返されたバリアントを格納したint64は私が期待していた結果のために十分に公正だったと仮定することにより、デルファイ5 でサポートされていないタイプUInt64型のVariant型を返したWMI呼び出し、 1-ました(Real Type) 2必要に応じてExtendedからInt64を返すTrunc関数を使用しました。

あなたが望むものではありませんが、Real Typeを考えると、誰かが「不可能な」Delphi 5の数学を達成するのに役立つかもしれません。

関連する問題