[英]Converting System.Decimal to System.Guid
我有一個大字典,其中鍵是十進制的,但System.Decimal的GetHashCode()非常糟糕。 為了證明我的猜測,我運行了一個帶有100.000 neigboring小數的for循環並檢查了分布。 100.000個不同的十進制數僅使用2個(兩個!!!)不同的哈希碼。
十進制表示為16個字節。 就像Guid一樣! 但是Guid的GetHashCode()發行版非常好。 如何在C#中將小數轉換為Guid盡可能便宜? 不安全的代碼沒問題!
編輯:請求測試,所以這里是代碼:
decimal d = 96000000000000000000m;
Dictionary<int, int> hashcount = new Dictionary<int, int>();
int length = 100000;
for (int i = 0; i < length; i++)
{
int hashcode = d.GetHashCode();
int n;
if (hashcount.TryGetValue(hashcode, out n))
{
hashcount[hashcode] = n + 1;
}
else
{
hashcount.Add(hashcode, 1);
}
d++;
}
Console.WriteLine(hashcount.Count);
這打印7.我不記得給我2的起始小數。
public static class Utils
{
[StructLayout(LayoutKind.Explicit)]
struct DecimalGuidConverter
{
[FieldOffset(0)]
public decimal Decimal;
[FieldOffset(0)]
public Guid Guid;
}
private static DecimalGuidConverter _converter;
public static Guid DecimalToGuid(decimal dec)
{
_converter.Decimal = dec;
return _converter.Guid;
}
public static decimal GuidToDecimal(Guid guid)
{
_converter.Guid = guid;
return _converter.Decimal;
}
}
// Prints 000e0000-0000-0000-8324-6ae7b91d0100
Console.WriteLine(Utils.DecimalToGuid((decimal) Math.PI));
// Prints 00000000-0000-0000-1821-000000000000
Console.WriteLine(Utils.DecimalToGuid(8472m));
// Prints 8472
Console.WriteLine(Utils.GuidToDecimal(Guid.Parse("00000000-0000-0000-1821-000000000000")));
如果您只是想獲得不同的哈希算法,則無需轉換為Guid。 像這樣的東西:
public int GetDecimalHashCode(decimal value)
{
int[] bits = decimal.GetBits(value);
int hash = 17;
foreach (int x in bits)
{
hash = hash * 31 + x;
}
return hash;
}
(如果你願意,顯然可以用不同的算法代替。)
不可否認,這仍然涉及創建一個不理想的陣列。 如果你真的想創建一個Guid,你可以使用上面的代碼獲取位,然后使用一個長的Guid
構造函數從數組中傳入適當的值。
我有點懷疑decimal
哈希碼是如此糟糕。 你有一些示例代碼嗎?
將您的十進制值轉換為字節數組,然后從中創建一個guid:
public static byte[] DecimalToByteArray (decimal src)
{
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(src);
return stream.ToArray();
}
}
}
Decimal myDecimal = 1234.5678M;
Guid guid = new Guid(DecimalToByteArray(myDecimal));
GUID的分布很好,因為它意味着獨特......
用於此的數字范圍是多少? Decimal
的默認GetHashcode()
實現可能只考慮一定范圍的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.