我有一些低级图像/纹理操作,其中32位颜色以UInt32或int的形式存储,我需要一种快速的按位转换方法。例如:
任何想法吗?
谢谢和问候。
int color = -2451337;
//exception
UInt32 cu = (UInt32)color;
任何想法吗?
谢谢和问候。
int color = -2451337;
unchecked {
uint color2 = (uint)color;
// color2 = 4292515959
}
BitConverter.ToUInt32(BitConverter.GetBytes(-2451337), 0)
这个问题和答案都很老了,自从那时候提问以来语言和标准库已经发生了很大的变化,但是我会提供一个更加“现代”的回答,适用于目前的时代。
using System.Runtime.CompilerServices;
int color = -2451337;
uint unsigned = Unsafe.As<int, uint>(ref color);
这里的优势在于没有装箱或强制转换,即使使用unchecked
仍然会发生。这只是提供了一种不同的方式来查看相同的位,类似于在C语言中重新解释指针类型。
与类名为Unsafe
相反,这不被认为是unsafe
代码,并且在将枚举转换为/从整数类型时避免装箱也很有效,尽管必须确保枚举与整数类型具有相同数量的位。
语言开发人员在此处对此技术进行了一些讨论。
对于那些使用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'条件的需要。