将负数转换为无符号类型(ushort, int或ulong)

本文关键字:ushort int ulong 类型 转换 无符号 | 更新日期: 2023-09-27 18:18:29

如何将某个负数转换为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

将负数转换为无符号类型(ushort, int或ulong)

只有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

更新10/10/2017

在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说它们具有相同的大小,通用实现将允许将任何非托管结构转换为任何其他非托管结构(这里不打算深入研究整个sizeofMarshal.SizeOf()的事情)。如果你知道你只是在转换基本的整数类型,那应该没问题。