【问题标题】:How do I convert 'Single' to binary?如何将“单”转换为二进制?
【发布时间】:2020-01-21 23:31:47
【问题描述】:

我正在整理一些扩展方法,用于将数值转换为其二进制等价物。

但我遇到了问题。

我们可以使用Convert.ToString() 重载将这些类型转换为二进制:

Byte
Short
Integer
Long

例如:

Dim iInteger As Integer
Dim sBinary As String

iInteger = Integer.MaxValue
sBinary = Convert.ToString(iInteger, 2)

Single 没有接受基值的重载。单参数重载返回科学计数法,而不是二进制值。

我试过这段代码,改编自this answer:

Public Function ToBinary(Value As Single) As String
  Dim aBits As Integer()

  Dim _
    iLength,
    iIndex As Integer

  Select Case Value
    Case < BitLengths.BYTE : iLength = 7
    Case < BitLengths.WORD : iLength = 15
    Case < BitLengths.DWORD : iLength = 31
    Case < BitLengths.QWORD : iLength = 63
  End Select

  aBits = New Integer(iLength) {}

  For iIndex = 0 To iLength
    aBits(iLength - iIndex) = Value Mod 2
    Value \= 2
  Next

  ToBinary = String.Empty

  aBits.ForEach(Sub(Bit)
                  ToBinary &= Bit
                End Sub)
End Function

不幸的是,它返回的结果不准确:

Input: 1361294667
Result: Assert.AreEqual failed. Expected:<01010001001000111011010101001011>. Actual:<01010001001000111011010110000000>.

我们可以从旧 Windows 7 计算器的 Programmer View 中得到期望值:

鉴于这些,我们如何可靠地将Single 值转换为二进制字符串?

--编辑--

我发现this statement“没有 0.1 或 0.01 的精确二进制表示。” 这几乎说明了一切。我决定放弃这个,因为很明显这种努力是徒劳的。

【问题讨论】:

  • 这是 BASIC 吗?无论是哪种语言,请用它标记您的帖子。
  • 目前还不清楚“准确结果”应该是什么样子。 Single 是一个浮点数,它的二进制表示看起来像like this。注意专用于符号、尾数和指数的位。您可以将它们转储为由 32 个 1 和 0 组成的字符串,但该字符串的意义很小。代码 sn-p 只关注值,这很快就会变得不切实际。取1E38,取127位,其中只有前24位是非随机值。
  • 所以表示值是不行的。在 vb.net 中很难做到这一点,您需要使用转换技巧从 Single 映射到 Integer。检查 this post 以获得 Caster 结构。
  • 这个问题是discussed at meta
  • ...twice.

标签: c# vb.net binary type-conversion


【解决方案1】:

您提供的示例期望值只是数字的直接二进制表示,但是如果您想获得二进制数字的 IEEE-754 表示,则可能不是最有效的方法,您可以使用BitConverter.GetBytes如下例:

Sub Main
    Dim i As Int32 = 1361294667
    Console.WriteLine(ObjectAsBinary(i))
    Dim s As Single = 1361294667
    Console.WriteLine(ObjectAsBinary(s))
End Sub

Private Function ObjectAsBinary(o As Object) As String
    Dim bytes = BitConverter.GetBytes(o)
    If BitConverter.IsLittleEndian Then
        Array.Reverse(bytes)
    End If
    Dim result As String = ""
    For Each b In bytes
        result &= Convert.ToString(b, 2).PadLeft(8, "0")
    Next
    Return result
End Function

该代码输出以下内容:

01010001001000111011010101001011 - 符合您的示例

01001110101000100100011101101011 - 匹配来自 IEEE-754 Floating Point Converter 的 IEEE-754

【讨论】:

  • 我不确定我是否理解。当它们的起始值相同时,为什么这两个结果不同?
  • @InteXX 第一个是整数的直接二进制数字表示,对于单浮点它有点复杂,二进制看起来像这样:en.wikipedia.org/wiki/…
  • 我找到了this statement“没有 0.1 或 0.01 的精确二进制表示。” 这几乎说明了一切。我决定放弃这个,因为很明显这种努力是徒劳的。
猜你喜欢
  • 2011-09-04
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 2023-04-11
  • 1970-01-01
相关资源
最近更新 更多