【问题标题】:Converting two bytes to an IEEE-11073 16-bit SFLOAT in C#在 C# 中将两个字节转换为 IEEE-11073 16 位 SFLOAT
【发布时间】:2026-01-28 12:10:01
【问题描述】:

我需要根据 IEEE-11073 将一个两字节数组转换为 SFloat 格式。

我该怎么做?

我在这里回答我的问题。

    public float ToSFloat(byte[] value)
    {
        if (value.Length != 2)
            throw new ArgumentException();
        byte b0 = value[0];
        byte b1 = value[1];


        var mantissa = unsignedToSigned(ToInt(b0) + ((ToInt(b1) & 0x0F) << 8), 12);
       var exponent = unsignedToSigned(ToInt(b1) >> 4, 4);

        return (float)(mantissa * Math.Pow(10, exponent));

    } 

    public int ToInt(byte value)
    {
        return value & 0xFF;
    }

    private int unsignedToSigned(int unsigned, int size) 
    {
        if ((unsigned & (1 << size-1)) != 0) 
     {
            unsigned = -1 * ((1 << size-1) - (unsigned & ((1 << size-1) - 1)));
        }        
        return unsigned;
    }

【问题讨论】:

  • 嗨 Jovirus,欢迎来到 *。你试过什么了?你的方法有什么问题?如果 * 上的问题不包含具有特定问题的代码,它们将很快被关闭。
  • .. 我发现上面的问题与 Java 有关,但您应该能够将相同的原则应用于 C#。
  • @WaiHaLee 我解决了它,并将我的答案放在我的问题中。

标签: c# floating-point ieee-11073


【解决方案1】:
   public float ToSFloat(byte[] value)
{
    if (value.Length != 2)
        throw new ArgumentException();
    byte b0 = value[0];
    byte b1 = value[1];


    var mantissa = unsignedToSigned(ToInt(b0) + ((ToInt(b1) & 0x0F) << 8), 12);
   var exponent = unsignedToSigned(ToInt(b1) >> 4, 4);

    return (float)(mantissa * Math.Pow(10, exponent));

} 

public int ToInt(byte value)
{
    return value & 0xFF;
}

private int unsignedToSigned(int unsigned, int size) 
{
    if ((unsigned & (1 << size-1)) != 0) 
 {
        unsigned = -1 * ((1 << size-1) - (unsigned & ((1 << size-1) - 1)));
    }        
    return unsigned;
}

【讨论】:

    【解决方案2】:

    大致基于C implementation by Signove on GitHub我在C#中创建了这个函数:

    Dictionary<Int32, Single> reservedValues = new Dictionary<Int32, Single> {
      { 0x07FE, Single.PositiveInfinity },
      { 0x07FF, Single.NaN },
      { 0x0800, Single.NaN },
      { 0x0801, Single.NaN },
      { 0x0802, Single.NegativeInfinity }
    };
    
    Single Ieee11073ToSingle(Byte[] bytes) {
      var ieee11073 = (UInt16) (bytes[0] + 0x100*bytes[1]);
      var mantissa = ieee11073 & 0x0FFF;
      if (reservedValues.ContainsKey(mantissa))
        return reservedValues[mantissa];
      if (mantissa >= 0x0800)
        mantissa = -(0x1000 - mantissa);
      var exponent = ieee11073 >> 12;
      if (exponent >= 0x08)
        exponent = -(0x10 - exponent);
      var magnitude = Math.Pow(10d, exponent);
      return (Single) (mantissa*magnitude);
    }
    

    此函数假定字节为小端格式。如果不是,则必须在函数的第一行交换 bytes[0]bytes[1]。或者甚至更好地从函数中删除第一行并将函数参数更改为接受UInt16(IEEE 11073 值),然后让调用者决定如何从输入中提取该值。

    我强烈建议您测试此代码,因为我没有任何测试值来验证转换的正确性。

    【讨论】:

    • 感谢您的回答