vb.net 中的 IEEE754 半精度(16 位)浮点数据

IEEE754 Half Precision (16 bit) floating point data in vb.net

VB.Net是否支持 IEEE 754 半精度(16 位)浮点数据类型? 如果没有,是否有推荐的创建方法?

上下文:我最终通过 COM 通道将字节流发送到接受半精度值的设备。我需要将用户输入的 Decimal 值转换为两个字节的浮点数进行传输。我不确定在 VB.Net

中执行此操作的最佳方法

我与这个库完全没有关联,但你可以使用 this

它是一个内部使用 ushort 成员的结构,这应该是您要传输的内容。如果由于某种原因你不能直接传输结构,你可以只制作 value 字段 public,然后使用它(或使用 GetBytes() 方法)。

不过我不确定转换的精度,您应该试验一下。

该库是 C#,但将它作为 C# 项目添加到您的解决方案并从 Vb.Net

使用它应该没有问题

更新

我花时间在 Vb.net 中制作了一个 "safe" 最低版本。所有代码均来自该库,所有版权归他所有:

Public Class HalfPrecisionConverter
    Private Shared BaseTable As UShort() = GenerateBaseTable()
    Private Shared ShiftTable As SByte() = GenerateShiftTable()

    Private Shared Function GenerateBaseTable() As UShort()
        Dim intBaseTable = New UShort(511) {}
        For i = 0 To 255
            Dim e = CSByte(127 - i)
            If e > 24 Then
                ' Very small numbers map to zero
                intBaseTable(i Or &H0) = &H0
                intBaseTable(i Or &H100) = &H8000
            ElseIf e > 14 Then
                ' Small numbers map to denorms
                intBaseTable(i Or &H0) = CUShort(&H400 >> (18 + e))
                intBaseTable(i Or &H100) = CUShort((&H400 >> (18 + e)) Or &H8000)
            ElseIf e >= -15 Then
                ' Normal numbers just lose precision
                intBaseTable(i Or &H0) = CUShort((15 - e) << 10)
                intBaseTable(i Or &H100) = CUShort(((15 - e) << 10) Or &H8000)
            ElseIf e > -128 Then
                ' Large numbers map to Infinity
                intBaseTable(i Or &H0) = &H7c00
                intBaseTable(i Or &H100) = &Hfc00
            Else
                ' Infinity and NaN's stay Infinity and NaN's
                intBaseTable(i Or &H0) = &H7c00
                intBaseTable(i Or &H100) = &Hfc00
            End If
        Next

        Return intBaseTable
    End Function

    Private Shared Function GenerateShiftTable() As SByte()
        Dim intShiftTable = New SByte(511) {}
        For i = 0 To 255
            Dim e = CSByte(127 - i)
            If e > 24 Then
                ' Very small numbers map to zero
                intShiftTable(i Or &H0) = 24
                intShiftTable(i Or &H100) = 24
            ElseIf e > 14 Then
                ' Small numbers map to denorms
                intShiftTable(i Or &H0) = CSByte(e - 1)
                intShiftTable(i Or &H100) = CSByte(e - 1)
            ElseIf e >= -15 Then
                ' Normal numbers just lose precision
                intShiftTable(i Or &H0) = 13
                intShiftTable(i Or &H100) = 13
            ElseIf e > -128 Then
                ' Large numbers map to Infinity
                intShiftTable(i Or &H0) = 24
                intShiftTable(i Or &H100) = 24
            Else
                ' Infinity and NaN's stay Infinity and NaN's
                intShiftTable(i Or &H0) = 13
                intShiftTable(i Or &H100) = 13
            End If
        Next

        Return intShiftTable
    End Function

    Public Shared Function SingleToHalf([single] As Single) As UShort
        Dim value As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes([single]), 0)

        Dim result = CUShort(baseTable((value >> 23) And &H1ff) + ((value And &H7fffff) >> shiftTable(value >> 23)))
        Return result
    End Function
End Class

使用:

HalfPrecisionConverter.SingleToHalf(xx)

就是returns一个UShort,如果需要字节数传输,可以用BitConverter.GetBytes()

C# 不安全版本应该快一点,因为它不使用 BitConverter 而是直接使用指针将单个字节转换为 UInteger 个字节,但我不确定 VB.NET 允许任何类型的指针转​​换