在 C# 中将数字转换为字节而不分配

问题描述 投票:0回答:3

如何将数值(例如

float
short
int
...)转换为多个
byte
值,而无需像
System.BitConverter.GetBytes
那样在堆上为数组分配内存?

类似这样的:

public static void GetBytes(short input, out byte byte0, out byte byte1)
{
    //demo code, just to show which results I need
    var bytes = System.BitConverter.GetBytes(input);
    byte0 = bytes[0];
    byte1 = bytes[1];
}

注意:我仅限于 .NET Framework 4.8,因此(我认为)C# 7.3。

c# arrays math garbage-collection
3个回答
5
投票

只需施放并移动?

public static void GetBytes(short input, out byte byte0, out byte byte1)
{
    byte0 = (byte)input;
    byte1 = (byte)(input >> 8);
}

请注意,您可以简单地反转不同字节顺序的顺序。

请注意,如果您使用“已检查”上下文,则还需要屏蔽:

public static void GetBytes(short input, out byte byte0, out byte byte1)
{
    byte0 = (byte)(input & 0xFF);
    byte1 = (byte)((input >> 8) & 0xFF);
}

(在未经检查的上下文中,转换为

byte
本身就足够了 - 额外的位被丢弃)


2
投票

如果允许使用不安全代码,那么对于非整数值类型(例如

float
double
decimal
),最快的方法是使用指针。

例如,对于

double

double x = 123.456;

unsafe
{
    byte* p = (byte*) &x;

    // Doubles have 8 bytes.

    byte b0 = *p++;
    byte b1 = *p++;
    byte b2 = *p++;
    byte b3 = *p++;
    byte b4 = *p++;
    byte b5 = *p++;
    byte b6 = *p++;
    byte b7 = *p;
}

您应该能够看到如何针对其他类型修改它。

对于诸如

short
int
long
之类的整数类型,您可以使用 Mark Gravell 的其他答案中给出的方法 - 但您也可以对整数类型使用上面的指针方法。

重要提示:使用指针方法时,字节序非常重要!字节分配的顺序就是它们在内存中存储的顺序,这可能因处理器架构而异。


0
投票

您可以在此处放置任何 ValueType。

public static Span<byte> AsSpan<T>(ref T val) where T : unmanaged
{
    Span<T> valSpan = MemoryMarshal.CreateSpan(ref val, 1);
    return MemoryMarshal.Cast<T, byte>(valSpan);
}

然后你可以反过来做。

public static T Convert<T>(ref Span<byte> span) where T : unmanaged
{
    return MemoryMarshal.Read<T>(span);
}

用途:

    int i = 123;
    float f = 0.000_1f;
        
    Span<byte> spanInt = AsSpan(ref i);
    Span<byte> spanFloat =AsSpan (ref f);

    int i2 = Convert<int>(ref spanInt);
    float f2 = Convert<float>(ref spanFloat);
        
    Console.Write($"{i2} {f2}");
© www.soinside.com 2019 - 2024. All rights reserved.