Fastest way to cast int to UInt32 bitwise?
Asked Answered
P

4

9

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

Populate answered 30/8, 2010 at 13:41 Comment(0)
S
24
int color = -2451337;
unchecked {
    uint color2 = (uint)color;
    // color2 = 4292515959
}
Sosthenna answered 30/8, 2010 at 13:46 Comment(0)
S
12
BitConverter.ToUInt32(BitConverter.GetBytes(-2451337), 0)
Skill answered 30/8, 2010 at 13:43 Comment(2)
+1 to offset the downvote. Even before my edit there was nothing of vital importance wrong with this answer. In fact, this would be the preferred method if using VB since direct casts from Int32 to UInt32 and granular unchecked contexts are not allowed.Anderaanderea
How does that compare in performance with something like UiValue = CUInt(IntValue & 0xFFFFFFFF&) ?Tshombe
S
3

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.

Suppositive answered 31/3, 2023 at 23:55 Comment(0)
T
0

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.

Tshombe answered 30/8, 2010 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.