将int型数据按位转换为UInt32的最快方法是什么?

9
我有一些低级图像/纹理操作,其中32位颜色以UInt32或int的形式存储,我需要一种快速的按位转换方法。例如:
 int color = -2451337;  

 //exception
 UInt32 cu = (UInt32)color;

任何想法吗?
谢谢和问候。
4个回答

24
int color = -2451337;
unchecked {
    uint color2 = (uint)color;
    // color2 = 4292515959
}

12
BitConverter.ToUInt32(BitConverter.GetBytes(-2451337), 0)

4
+1 抵消了负投票。即使在我的编辑之前,这个回答并没有什么重要的错误。事实上,如果使用 VB,这将是首选方法,因为从 Int32 直接转换为 UInt32 和细粒度未经检查的上下文都是不被允许的。 - Brian Gideon
这种方法的性能与 UiValue = CUInt(IntValue & 0xFFFFFFFF&) 相比如何? - supercat

2

这个问题和答案都很老了,自从那时候提问以来语言和标准库已经发生了很大的变化,但是我会提供一个更加“现代”的回答,适用于目前的时代。

using System.Runtime.CompilerServices;

int color = -2451337;  
uint unsigned = Unsafe.As<int, uint>(ref color);

这里的优势在于没有装箱或强制转换,即使使用unchecked仍然会发生。这只是提供了一种不同的方式来查看相同的位,类似于在C语言中重新解释指针类型。

与类名为Unsafe相反,这不被认为是unsafe代码,并且在将枚举转换为/从整数类型时避免装箱也很有效,尽管必须确保枚举与整数类型具有相同数量的位。

语言开发人员在此处对此技术进行了一些讨论。


0

对于那些使用VB等语言的人来说,在转换期间没有真正方便的禁用溢出检查的方法,可以使用以下代码:

    Shared Function unsToSign64(ByVal val As UInt64) As Int64
        If (val And &H8000000000000000UL)  0 Then Return CLng(val Xor &H8000000000000000UL) Xor &H8000000000000000 Else Return CLng(val)
    End Function
    Shared Function signToUns64(ByVal val As Int64) As UInt64
        If val < 0 Then Return CULng(val Xor &H8000000000000000) Xor &H8000000000000000UL Else Return CULng(val)
    End Function

或者

    共享函数 unsToSign(ByVal val As UInt64) As Int64
        返回 CLng(val And &H7FFFFFFFFFFFFFFFUL) + (CLng(-((val And &H8000000000000000UL) >> 1)) << 1)
    End Function
    共享函数 signToUns(ByVal val As Int64) As UInt64
        返回 CULng(val And &H7FFFFFFFFFFFFFFF) + (CULng(-((val And &H8000000000000000) >> 1)) << 1)
    End Function

32位版本将非常相似。我不确定哪种方法更快。这些移位操作有点愚蠢,但它们避免了对'if'条件的需要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接