在XmlConvert.ToSingle中奇怪-0f

时间:2017-08-07 20:29:34

标签: c# .net xml .net-core

来自.net:https://github.com/Microsoft/referencesource/blob/master/System.Xml/System/Xml/XmlConvert.cs#L1035

的代码
Sub ScanButtonInForm1()
    Dim frm2 As Form2 = New Form2
    frm2.Show()
    Dim AlreadyScanned As HashSet(Of String) = New HashSet(Of String)
    Dim stack As New Stack(Of String)
    stack.Push("...Directoy To Start The Search From...")
    Do While (stack.Count > 0)
        frm2.Label4.Text = "-- Mapping Files... -- Folders Left:" + stack.Count.ToString + " -- Files Found:" + frm2.ListBox1.Items.Count.ToString + " --"
        frm2.Label4.Refresh()
        Dim ScanDir As String = stack.Pop
        If AlreadyScanned.Add(ScanDir) Then
            Try
                Try
                    Try
                        Dim directoryName As String
                        For Each directoryName In System.IO.Directory.GetDirectories(ScanDir)
                            stack.Push(directoryName)
                            frm2.Label4.Text = "-- Mapping Files... -- Folders Left:" + stack.Count.ToString + " -- Files Found:" + frm2.ListBox1.Items.Count.ToString + " --"
                            frm2.Label4.Refresh()
                        Next
                        frm2.ListBox1.Items.AddRange(System.IO.Directory.GetFiles(ScanDir, "*.*", System.IO.SearchOption.AllDirectories))
                    Catch ex5 As UnauthorizedAccessException
                    End Try
                Catch ex2 As System.IO.PathTooLongException
                End Try
            Catch ex4 As System.IO.DirectoryNotFoundException
            End Try
        End If
    Loop
End Sub

我无法理解这里发生的事情......
假设浮点数与0.0的比较是可以的,因为它是零并且所有位都是零。所以在理论上它应该等于0.0f;所以零的二进制表示应该是相同的。

但是什么是-0.0f?这些代码的目的是什么?

  

>等于-0.0f
  0

     

> (等于-0.0f)的ToString()
  “0”

     

> -0.0f == 0.0f
  真

     

> (等于-0.0f)的ToString( “+ 0; - #”)
  “0”

     

> (-1.0F)的ToString( “+ 0; - #”)
  “-1”

2 个答案:

答案 0 :(得分:2)

This wiki文章回答了这个问题。

  

带符号的零为零,带有相关符号。在普通的算术中,   数字0没有符号,因此-0,+ 0和0是相同的。   但是,在计算中,一些数字表示允许   存在两个零,通常用-0(负零)和+0表示   (正零),通过数值比较视为相等   操作,但特别是可能有不同的行为   操作。这发生在符号和幅度以及补码中   整数的有符号数表示,大多数是浮点数   数字表示。数字0通常编码为+0,但可以   用+0或-0表示。

     

用于浮点运算的IEEE 754标准(目前由...使用)   大多数支持浮点的计算机和编程语言   数字)需要+0和-0。带有符号零的实数算术   可以被认为是扩展实数行的变体   1 / -0 =-∞且1 / + 0 = +∞;除法仅为±0 /±0和未定义   ±∞/±∞。

答案 1 :(得分:1)

我想我已经弄清楚了......

Kevin Goose谈到了不同的二元表示法:

  

我不知道影响,但0.0f和-0.0f没有相同的二进制代表:

Console.WriteLine(string.Join(", ", BitConverter.GetBytes(0.0f)));
Console.WriteLine(string.Join(", ", BitConverter.GetBytes(-0.0f)));

// Output
0, 0, 0, 0   
0, 0, 0, 128

我想我知道影响力 ......看看输出......这是Little-Endian。所以最大(最重要)的第31位设置为1.该位负责数字内的正/负标志 因此,当它设置为1时,该位​​表示"数字为负数"。

为什么我们需要它?我已经从维基百科的文章中分析了所有可能的案例(感谢Sam),最后我可以说只需要得到负无穷大作为结果......别的......所有其他只是这个事实的后果。

  

> (1.0f / -0.0f)
  -Infinity

     

> (1.0f / + 0.0f)
  无穷大

由于负位允许我们在计算中得到负无穷大,我可以说在解析XML期间不丢失负位非常重要。这是XmlConvert中此类代码的原因 因为float.Parse在历史上非常具体。它给我们总是+0.0因此正无穷大:

  

> 1.0f / float.Parse(" -0.0")
  无穷大