将 int 按位转换为 UInt32 的最快方法?

发布于 2024-09-16 16:55:11 字数 203 浏览 7 评论 0原文

我有一些低级图像/纹理操作,其中 32 位颜色存储为 UInt32 或 int,并且我需要在两者之间进行非常快速的按位转换。

例如

 int color = -2451337;  

 //exception
 UInt32 cu = (UInt32)color;

有什么想法吗?

谢谢和问候

i have some low level image/texture operations where 32-bit colors are stored as UInt32 or int and i need a really fast bitwise conversion between the two.

e.g.

 int color = -2451337;  

 //exception
 UInt32 cu = (UInt32)color;

any ideas?

thanks and regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔戏命师 2024-09-23 16:55:11
int color = -2451337;
unchecked {
    uint color2 = (uint)color;
    // color2 = 4292515959
}
int color = -2451337;
unchecked {
    uint color2 = (uint)color;
    // color2 = 4292515959
}
月亮是我掰弯的 2024-09-23 16:55:11
BitConverter.ToUInt32(BitConverter.GetBytes(-2451337), 0)
BitConverter.ToUInt32(BitConverter.GetBytes(-2451337), 0)
且行且努力 2024-09-23 16:55:11

这个问题和答案已经很老了,自最初提出以来,语言和标准库已经发展了很多,但我将提供一个适用于时代的更“现代”的答案。

using System.Runtime.CompilerServices;

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

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

Unsafe 的类名称相反,这并不被认为是 不安全 代码,并且还可以很好地避免在与整数类型转换时对枚举进行装箱,但必须确保枚举与整数类型的位数相同。

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

This question and the answers are quite old, and the language and standard library have evolved quite a bit since it was originally asked, but I will supply a more "modern" answer that is applicable for the times.

using System.Runtime.CompilerServices;

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

The advantage here is that there is no boxing or cast, which is still occurring even when using unchecked. This merely provides a different way of looking at the same bits, analogous to reinterpreting a pointer type in a language like C.

Contrary to the name of the class being Unsafe, this is not considered unsafe code, and also works well for avoiding boxing of enums when converting to/from integral types, though one must ensure that the enum is the same number of bits as the integer type.

There is some discussion of this technique by the language developers here.

酒与心事 2024-09-23 16:55:11

那些使用像 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

    Shared Function unsToSign(ByVal val As UInt64) As Int64
        Return CLng(val And &H7FFFFFFFFFFFFFFFUL) + (CLng(-((val And &H8000000000000000UL) >> 1)) << 1)
    End Function
    Shared Function signToUns(ByVal val As Int64) As UInt64
        Return CULng(val And &H7FFFFFFFFFFFFFFF) + (CULng(-((val And &H8000000000000000) >> 1)) << 1)
    End Function

32 位的版本将非常相似。我不确定哪种方法会更快。这些转变有点愚蠢,但它们避免了“if”测试的需要。

Those using a language like VB, which don't have a really convenient way of disabling overflow checks during the conversion, could use something like:

    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

or

    Shared Function unsToSign(ByVal val As UInt64) As Int64
        Return CLng(val And &H7FFFFFFFFFFFFFFFUL) + (CLng(-((val And &H8000000000000000UL) >> 1)) << 1)
    End Function
    Shared Function signToUns(ByVal val As Int64) As UInt64
        Return CULng(val And &H7FFFFFFFFFFFFFFF) + (CULng(-((val And &H8000000000000000) >> 1)) << 1)
    End Function

Versions for 32 bits would be very similar. I'm not sure which approach would be faster. The shifts are a little silly, but they avoid the need for 'if' tests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文