将负数转换为无符号类型(ushort、uint 或 ulong)
Cast negative number to unsigned types (ushort, uint or ulong)
如何将一些负数转换为 unsigned types
。
Type type = typeof (ushort);
short num = -100;
ushort num1 = unchecked ((ushort) num); //When type is known. Result 65436
ushort num2 = unchecked(Convert.ChangeType(num, type)); //Need here the same value
只有4种。所以您可以为此编写自己的方法。
private static object CastToUnsigned(object number)
{
Type type = number.GetType();
unchecked
{
if (type == typeof(int)) return (uint)(int)number;
if (type == typeof(long)) return (ulong)(long)number;
if (type == typeof(short)) return (ushort)(short)number;
if (type == typeof(sbyte)) return (byte)(sbyte)number;
}
return null;
}
这是测试:
short sh = -100;
int i = -100;
long l = -100;
Console.WriteLine(CastToUnsigned(sh));
Console.WriteLine(CastToUnsigned(i));
Console.WriteLine(CastToUnsigned(l));
产出
65436
4294967196
18446744073709551516
2017 年 10 月 10 日更新
借助适用于泛型类型的 C# 7.1 模式匹配功能,您现在可以使用 switch 语句。
感谢@quinmars 的建议。
private static object CastToUnsigned<T>(T number) where T : struct
{
unchecked
{
switch (number)
{
case long xlong: return (ulong) xlong;
case int xint: return (uint)xint;
case short xshort: return (ushort) xshort;
case sbyte xsbyte: return (byte) xsbyte;
}
}
return number;
}
如果您可以使用 unsafe
代码,您总是可以编写这样的函数并使用指针进行转换:
public static unsafe TTo Convert<TFrom, TTo>(TFrom value) where TFrom : unmanaged where TTo : unmanaged
{
if (sizeof(TFrom) != sizeof(TTo))
{
throw new ArgumentException("Source and target types must be the same size!");
}
return *(TTo*)&value;
}
您可以这样使用:
short num = -100;
ushort uNum = Convert<short, ushort>(num);
这里的好处是没有装箱,没有类型检查,分配免费代码,如果你大胆并且知道你在做什么,你甚至可以删除大小检查以获得无分支实现。
这里明显的缺点是 unsafe
关键字,它在许多业务应用程序中通常是不可取的,并且通用实现将允许将任何非托管结构转换为任何其他非托管结构,只要 sizeof
表示它们是相同的大小(这里不会深入讨论整个 sizeof
与 Marshal.SizeOf()
的事情)。如果你知道你只是在转换原始整数类型,那应该没问题。
如何将一些负数转换为 unsigned types
。
Type type = typeof (ushort);
short num = -100;
ushort num1 = unchecked ((ushort) num); //When type is known. Result 65436
ushort num2 = unchecked(Convert.ChangeType(num, type)); //Need here the same value
只有4种。所以您可以为此编写自己的方法。
private static object CastToUnsigned(object number)
{
Type type = number.GetType();
unchecked
{
if (type == typeof(int)) return (uint)(int)number;
if (type == typeof(long)) return (ulong)(long)number;
if (type == typeof(short)) return (ushort)(short)number;
if (type == typeof(sbyte)) return (byte)(sbyte)number;
}
return null;
}
这是测试:
short sh = -100;
int i = -100;
long l = -100;
Console.WriteLine(CastToUnsigned(sh));
Console.WriteLine(CastToUnsigned(i));
Console.WriteLine(CastToUnsigned(l));
产出
65436
4294967196
18446744073709551516
2017 年 10 月 10 日更新
借助适用于泛型类型的 C# 7.1 模式匹配功能,您现在可以使用 switch 语句。
感谢@quinmars 的建议。
private static object CastToUnsigned<T>(T number) where T : struct
{
unchecked
{
switch (number)
{
case long xlong: return (ulong) xlong;
case int xint: return (uint)xint;
case short xshort: return (ushort) xshort;
case sbyte xsbyte: return (byte) xsbyte;
}
}
return number;
}
如果您可以使用 unsafe
代码,您总是可以编写这样的函数并使用指针进行转换:
public static unsafe TTo Convert<TFrom, TTo>(TFrom value) where TFrom : unmanaged where TTo : unmanaged
{
if (sizeof(TFrom) != sizeof(TTo))
{
throw new ArgumentException("Source and target types must be the same size!");
}
return *(TTo*)&value;
}
您可以这样使用:
short num = -100;
ushort uNum = Convert<short, ushort>(num);
这里的好处是没有装箱,没有类型检查,分配免费代码,如果你大胆并且知道你在做什么,你甚至可以删除大小检查以获得无分支实现。
这里明显的缺点是 unsafe
关键字,它在许多业务应用程序中通常是不可取的,并且通用实现将允许将任何非托管结构转换为任何其他非托管结构,只要 sizeof
表示它们是相同的大小(这里不会深入讨论整个 sizeof
与 Marshal.SizeOf()
的事情)。如果你知道你只是在转换原始整数类型,那应该没问题。