gpt4 book ai didi

c# - 在 C# 中将 ulong 映射到 long?

转载 作者:太空狗 更新时间:2023-10-29 23:05:41 24 4
gpt4 key购买 nike

我正在尝试将 ulong 映射到 long(反之亦然),并将 uint 映射到 int(反之亦然),如下所示 - 为了将值保存在 MS-SQL 数据库中仅限带符号类型的整数和双整数。

我这样做是因为我必须检查(在数据库中)一个数字(uint,ulong)是否在一堆 uint/ulong 范围(IPs - v4 & v6;实际上 ulong 实际上是一个uint128由两个ulong组成)。

UlongToLong

UIntToInt

有没有比我这里的代码更有效的方法来完成这个:

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);
}

最佳答案

选项 1:保序映射

这听起来像是您要一张保留顺序的 map ,这意味着,例如,如果 xyulong s 和 x < y , 然后 MapUlongToLong(x) < MapUlongToLong(y) .

方法如下:

映射自ulonglong , 类型转换并添加 long.MinValue .映射自long返回ulong , 减去 long.MinValue并投下。在任何一种情况下,都使用未经检查的上下文,以便忽略溢出条件。

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完全类似。

(选项一是我2016年写的原答案,我在2021年增加了选项二,以及两者的比较。)

选项 2:非保序映射

我认为这不是您要的,但如果您不关心保留顺序,则转换会更容易。

这些函数的工作方式与上述函数相同,只是我们不用费心去加减long.MinValue。 .

public static long MapUlongToLong(ulong ulongValue)
{
return unchecked((long)ulongValue);
}

public static ulong MapLongToUlong(long longValue)
{
return unchecked((ulong)longValue);
}

哪个选项更好?

选项 1 保留顺序而选项 2 不保留顺序,因此如果您需要保留顺序,请使用选项 1。

选项 1 中的函数执行需要多长时间?好吧,这些函数可能会被 JIT 编译器内联和优化,它们最终要求 CPU 做一些非常非常简单的事情。我猜测每个函数调用将花费不到 1 纳秒。

其中一条评论将这种不到一纳秒的执行时间描述为“相对较慢”。如果纳秒对您来说太慢,您可能需要使用选项 2。

选项 2 中的函数也可能会被 JIT 编译器内联和优化,事实证明,就 CPU 而言,这些函数几乎什么都不做。因此,不会为这些函数生成机器代码,因此每个函数调用根本不需要时间——换句话说,0 纳秒。

Aron's answer与选项 2 做同样的事情,我猜它也会同样快地运行。

关于c# - 在 C# 中将 ulong 映射到 long?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40900594/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com