我试图将ulong映射到long(反之亦然),并将uint映射到int(反之亦然),如下所示 – 以便将值保存在带有签名类型的MS-SQL数据库中仅限整数和大整数.
我这样做是因为我必须检查(在数据库中)一个数字(uint,ulong)是否在一堆uint / ulong范围内的哪个范围内(IPs-v4& v6;实际上ulong实际上是uint128组成的两个ulongs).
有没有更有效的方法来实现这一点,我有这里的代码:
public static ulong SignedLongToUnsignedLong(long signedLongValue)
{
ulong backConverted = 0;
// map ulong to long [ 9223372036854775808 = abs(long.MinValue) ]
if (signedLongValue < 0)
{
// Cannot take abs from MinValue
backConverted = (ulong)System.Math.Abs(signedLongValue - 1);
backConverted = 9223372036854775808 - backConverted - 1;
}
else
{
backConverted = (ulong)signedLongValue;
backConverted += 9223372036854775808;
}
return backConverted;
}
public static long UnsignedLongToSignedLong(ulong unsignedLongValue)
{
// map ulong to long [ 9223372036854775808 = abs(long.MinValue) ]
return (long) (unsignedLongValue - 9223372036854775808);
}
public static int UnsignedIntToSignedInt(uint unsignedIntValue)
{
// map uint to int [ 2147483648 = abs(long.MinValue) ]
return (int)(unsignedIntValue - 2147483648);
}
public static uint SignedIntToUnsignedInt(int signedIntValue)
{
uint backConverted = 0;
// map ulong to long [ 2147483648 = abs(long.MinValue) ]
if (signedIntValue < 0)
{
// Cannot take abs from MinValue
backConverted = (uint)System.Math.Abs(signedIntValue - 1);
backConverted = 2147483648 - backConverted - 1;
}
else
{
backConverted = (uint)signedIntValue;
backConverted += 2147483648;
}
return backConverted;
}
public static void TestLong()
{
long min_long = -9223372036854775808;
long max_long = 9223372036854775807;
ulong min_ulong = ulong.MinValue; // 0
ulong max_ulong = ulong.MaxValue; // 18446744073709551615 = (2^64)-1
long dbValueMin = UnsignedLongToSignedLong(min_ulong);
long dbValueMax = UnsignedLongToSignedLong(max_ulong);
ulong valueFromDbMin = SignedLongToUnsignedLong(dbValueMin);
ulong valueFromDbMax = SignedLongToUnsignedLong(dbValueMax);
System.Console.WriteLine(dbValueMin);
System.Console.WriteLine(dbValueMax);
System.Console.WriteLine(valueFromDbMin);
System.Console.WriteLine(valueFromDbMax);
}
public static void TestInt()
{
int min_int = -2147483648; // int.MinValue
int max_int = 2147483647; // int.MaxValue
uint min_uint= uint.MinValue; // 0
uint max_uint = uint.MaxValue; // 4294967295 = (2^32)-1
int dbValueMin = UnsignedIntToSignedInt(min_uint);
int dbValueMax = UnsignedIntToSignedInt(max_uint);
uint valueFromDbMin = SignedIntToUnsignedInt(dbValueMin);
uint valueFromDbMax = SignedIntToUnsignedInt(dbValueMax);
System.Console.WriteLine(dbValueMin);
System.Console.WriteLine(dbValueMax);
System.Console.WriteLine(valueFromDbMin);
System.Console.WriteLine(valueFromDbMax);
}
解决方法:
要从ulong映射到long,请强制转换并添加long.MinValue.要从long返回到ulong,请减去long.MinValue和cast.在任何一种情况下,都使用未经检查的上下文,以便忽略溢出条件.
public static long MapUlongToLong(ulong ulongValue)
{
return unchecked((long)ulongValue + long.MinValue);
}
public static ulong MapLongToUlong(long longValue)
{
return unchecked((ulong)(longValue - long.MinValue));
}
uint和int的逻辑完全相似.