明らかPigeonhole Principleによって、我々は2^128 - 2^64
に等しい少なくとも2^64 * (2^64 -1)
サイズの出力を必要とするので、ユニーク単一番号に2つの64ビット整数を符号化するために、可能な入力の2^64 * (2^64 -1)
組み合わせが存在する、すなわちすべての可能な出力を保持するには128ビットの容量が必要です。
私はそれがすべての値のために存在することはできません知っています。しかし、それは値に依存し、データ型には依存しません。例えば。 4と5が64ビットの整数として格納されていても、f(4,5)を実行することはできます。オーバーフローのために、使用される関数に応じてチェックするのは簡単です(その場合はマッピングを使用しません)。
あなたはそれを知っています。つまり、64ビット入力の最大値を上限にすることができます。出力は64ビット符号または符号なし整数になります。
出力が署名され、C#で実装:符号なしの実装がわずかに速いためのあろう
public static ulong GetHashCode(long a, long b)
{
if (a < int.MinValue || a > int.MaxValue || b < int.MinValue || b > int.MaxValue)
throw new ArgumentOutOfRangeException();
var A = (ulong)(a >= 0 ? 2 * a : -2 * a - 1);
var B = (ulong)(b >= 0 ? 2 * b : -2 * b - 1);
return A >= B ? A * A + A + B : A + B * B;
}
:
public static long GetHashCode(long a, long b)
{
if (a < int.MinValue || a > int.MaxValue || b < int.MinValue || b > int.MaxValue)
throw new ArgumentOutOfRangeException();
var A = (ulong)(a >= 0 ? 2 * a : -2 * a - 1);
var B = (ulong)(b >= 0 ? 2 * b : -2 * b - 1);
var C = (long)((A >= B ? A * A + A + B : A + B * B)/2);
return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}
出力は、C#で実装符号なしですより少ない計算。ユニークペアの下限と上限は、int.MaxValue
(-2147483648)とint.MaxValue
(2147483647)です。元の関数はtaken from hereです。リンクに記載されているエレガントなペアリング機能は、使用可能なスペースのすべての単一ポイントにマップされるため、最もスペース効率が高い可能性があります。同様の方法の詳細については、Mapping two integers to one, in a unique and deterministic way
Haroldを参照してください。私が言ったように、すべての値に対して存在することはできません。しかし、それは値に依存し、データ型には依存しません。例えば。 4と5が64ビットの整数として格納されていても、f(4,5)を実行することはできます。オーバーフローのために、使用される関数に応じてチェックするのは簡単です(その場合はマッピングを使用しません)。私は、可逆性を緩和することがスペース使用量に関して何らかの利益をもたらすかどうか疑問に思っていただけです。 – cornuz
あなたの要件を満たす '(2 ^(2^128))^ 64 ' p.s.大きな数字を構成しない - これは128ビットから64ビットまでの関数の数です。 – amit
とにかくオーバーフローしない限り、 '((x + y)*(x + y)+ x - y)/ 2'はどうですか? – harold