Single Struktur

Definition

Stellt eine Gleitkommazahl mit einfacher Genauigkeit dar.

public value class float : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public value class float : IComparable, IComparable<float>, IConvertible, IEquatable<float>, ISpanFormattable
public value class float : IComparable, IConvertible, IFormattable
public value class float : IComparable, IComparable<float>, IEquatable<float>, IFormattable
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, ISpanFormattable
[System.Serializable]
public struct Single : IComparable, IConvertible, IFormattable
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public struct Single : IComparable, IComparable<float>, IEquatable<float>, IFormattable
type single = struct
    interface IConvertible
    interface IFormattable
type single = struct
    interface IConvertible
    interface ISpanFormattable
    interface IFormattable
[<System.Serializable>]
type single = struct
    interface IFormattable
    interface IConvertible
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type single = struct
    interface IFormattable
    interface IConvertible
type single = struct
    interface IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IConvertible, IEquatable(Of Single), IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IConvertible, IEquatable(Of Single), ISpanFormattable
Public Structure Single
Implements IComparable, IConvertible, IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IEquatable(Of Single), IFormattable
Vererbung
Single
Attribute
Implementiert

Hinweise

Der Werttyp stellt eine 32-Bit-Zahl mit nur einer Genauigkeit mit Werten im Bereich von Single negativem 3,402823e38 bis positivem 3,402823e38 sowie positiven oder negativen Nullen, , und nicht einer Zahl PositiveInfinity ( ) NegativeInfinity NaN dar. Sie soll Werte darstellen, die extrem groß (z. B. Entfernungen zwischen Planeten oder Planeten) oder äußerst klein (z. B. die 10000000000000Erde in 2017) und häufig unpräzise sind (z. B. die Entfernung von der Erde zu einem anderen Sonnensystem). Der Single Typ entspricht dem IEC 60559:1989-Standard (IEEE 754) für binäre Gleitkommaarithmetik.

Dieser Artikel besteht aus den folgenden Abschnitten:

System.Single stellt Methoden zum Vergleichen von Instanzen dieses Typs, zum Konvertieren des Werts einer Instanz in ihre Zeichenfolgendarstellung und zum Konvertieren der Zeichenfolgendarstellung einer Zahl in eine Instanz dieses Typs zurVerfingung von Methoden zur Zeichenfolgendarstellung zurEntspricht. Informationen dazu, wie Formatspezifikationscodes die Zeichenfolgendarstellung von Werttypen steuern, finden Sie unter Formatierenvon Typen , Standardmäßigenumerische Formatzeichenfolgen und Benutzerdefinierte numerische Formatzeichenfolgen.

Gleitkommadarstellung und Genauigkeit

Der -Datentyp speichert Gleitkommawerte mit einzelner Genauigkeit in einem Single 32-Bit-Binärformat, wie in der folgenden Tabelle gezeigt:

Teil Bits
Mantisse oder Mantisse 0-22
Exponent 23-30
Vorzeichen (0 = positiv, 1 = negativ) 31

Ebenso wie Dezimalbruchzahlen einige Bruchwerte (z. B. 1/3 oder ) nicht genau darstellen können, können binäre Bruchzahlen einige Math.PI Bruchwerte nicht darstellen. Beispielsweise wird 2/10, das genau durch .2 als Dezimalbruch dargestellt wird, von .0011111001001100 als binärer Bruch dargestellt, und das Muster "1100" wiederholt sich in unendlich. In diesem Fall stellt der Gleitkommawert eine unpräzise Darstellung der Zahl dar, die er darstellt. Das Ausführen zusätzlicher mathematischer Operationen für den ursprünglichen Gleitkommawert erhöht häufig die Genauigkeit. Wenn Sie z. B. die Ergebnisse der Multiplikation von .3 mit 10 vergleichen und 0,3 bis 0,3 neun Mal hinzufügen, sehen Sie, dass diese Addition das weniger präzise Ergebnis erzeugt, da sie acht weitere Vorgänge als die Multiplikation umfasst. Beachten Sie, dass diese Ungleichheit nur sichtbar ist, wenn Sie die beiden Werte mithilfe der numerischen Standardformatzeichenfolge "R" anzeigen, die bei Bedarf alle vom Typ unterstützten 9 Dezimalziffern Single Single anzeigt.

using System;

public class Example
{
   public static void Main()
   {
      Single value = .2f;
      Single result1 = value * 10f;
      Single result2 = 0f;
      for (int ctr = 1; ctr <= 10; ctr++)
         result2 += value;

      Console.WriteLine(".2 * 10:           {0:R}", result1);
      Console.WriteLine(".2 Added 10 times: {0:R}", result2);
   }
}
// The example displays the following output:
//       .2 * 10:           2
//       .2 Added 10 times: 2.00000024
Module Example
   Public Sub Main()
      Dim value As Single = .2
      Dim result1 As Single = value * 10
      Dim result2 As Single
      For ctr As Integer = 1 To 10
         result2 += value
      Next
      Console.WriteLine(".2 * 10:           {0:R}", result1)
      Console.WriteLine(".2 Added 10 times: {0:R}", result2)
   End Sub
End Module
' The example displays the following output:
'       .2 * 10:           2
'       .2 Added 10 times: 2.00000024

Da einige Zahlen nicht genau als binäre Bruchwerte dargestellt werden können, können Gleitkommazahlen nur den tatsächlichen Zahlen ungefähren.

Alle Gleitkommazahlen verfügen über eine begrenzte Anzahl signifikanter Ziffern, wodurch auch bestimmt wird, wie genau ein Gleitkommawert einer echten Zahl entspricht. Ein Single Wert hat bis zu 7 Dezimalstellen der Genauigkeit, obwohl maximal 9 Ziffern intern beibehalten werden. Dies bedeutet, dass einigen Gleitkommavorgängen möglicherweise die Genauigkeit fehlt, um einen Gleitkommawert zu ändern. Im folgenden Beispiel wird ein großer Gleitkommawert mit einer genauigkeitsbasierten Genauigkeit definiert, und anschließend wird das Produkt von und eine Single.Epsilon Quadrillion hinzufügt. Das Produkt ist jedoch zu klein, um den ursprünglichen Gleitkommawert zu ändern. Die am wenigsten signifikante Ziffer ist Tausendstel, während die signifikanteste Ziffer im Produkt 10-30 ist.

using System;

public class Example
{
   public static void Main()
   {
      Single value = 123.456f;
      Single additional = Single.Epsilon * 1e15f;
      Console.WriteLine($"{value} + {additional} = {value + additional}");
   }
}
// The example displays the following output:
//    123.456 + 1.401298E-30 = 123.456
Module Example
   Public Sub Main()
      Dim value As Single = 123.456
      Dim additional As Single = Single.Epsilon * 1e15
      Console.WriteLine($"{value} + {additional} = {value + additional}")
   End Sub
End Module
' The example displays the following output:
'   123.456 + 1.401298E-30 = 123.456

Die eingeschränkte Genauigkeit einer Gleitkommazahl hat mehrere Folgen:

  • Zwei Gleitkommazahlen, die für eine bestimmte Genauigkeit identisch zu sein scheinen, können sich als unterschiedlich erweisen, wenn sich die zwei letzten Ziffern unterscheiden. Im folgenden Beispiel werden eine Reihe von Zahlen zusammengerechnet, und ihre Summe wird mit der erwarteten Summe verglichen. Obwohl die beiden Werte identisch zu sein scheinen, gibt ein Aufruf der -Methode Equals an, dass dies nicht der Wert ist.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          Single[] values = { 10.01f, 2.88f, 2.88f, 2.88f, 9.0f };
          Single result = 27.65f;
          Single total = 0f;
          foreach (var value in values)
             total += value;
    
          if (total.Equals(result))
             Console.WriteLine("The sum of the values equals the total.");
          else
             Console.WriteLine("The sum of the values ({0}) does not equal the total ({1}).",
                               total, result); 
       }
    }
    // The example displays the following output:
    //      The sum of the values (27.65) does not equal the total (27.65).   
    //
    // If the index items in the Console.WriteLine statement are changed to {0:R},
    // the example displays the following output:
    //       The sum of the values (27.6500015) does not equal the total (27.65).
    
    Module Example
       Public Sub Main()
          Dim values() As Single = { 10.01, 2.88, 2.88, 2.88, 9.0 }
          Dim result As Single = 27.65
          Dim total As Single
          For Each value In values
             total += value
          Next
          If total.Equals(result) Then
             Console.WriteLine("The sum of the values equals the total.")
          Else
             Console.WriteLine("The sum of the values ({0}) does not equal the total ({1}).",
                               total, result) 
          End If     
       End Sub
    End Module
    ' The example displays the following output:
    '      The sum of the values (27.65) does not equal the total (27.65).   
    '
    ' If the index items in the Console.WriteLine statement are changed to {0:R},
    ' the example displays the following output:
    '       The sum of the values (27.639999999999997) does not equal the total (27.64).
    

    Wenn Sie die Formatelemente in der Anweisung von und in und ändern, um alle signifikanten Ziffern der beiden Werte anzuzeigen, ist klar, dass die beiden Werte aufgrund eines Console.WriteLine(String, Object, Object) {0} Genauigkeitsverlusts während der {1} {0:R} {1:R} Additionsvorgänge ungleich Single sind. In diesem Fall kann das Problem durch Aufrufen der -Methode behoben werden, um die Werte vor dem Vergleich auf die Math.Round(Double, Int32) Single gewünschte Genauigkeit zu runden.

  • Eine mathematische oder Vergleichsoperation, die eine Gleitkommazahl verwendet, führt möglicherweise nicht zu demselben Ergebnis, wenn eine Dezimalzahl verwendet wird, da die binäre Gleitkommazahl möglicherweise nicht der Dezimalzahl entspricht. In einem vorherigen Beispiel wurde dies veranschaulicht, indem das Ergebnis der Multiplikation von .3 mit 10 und das neunmale Hinzufügen von 0,3 zu 0,3 angezeigt wurde.

    Wenn die Genauigkeit in numerischen Vorgängen mit Bruchwerten wichtig ist, verwenden Sie den Decimal Typ anstelle des Single Typs. Wenn die Genauigkeit in numerischen Vorgängen mit integralen Werten, die über den Bereich der Typen oder Int64 UInt64 hinausgehen, wichtig ist, verwenden Sie den BigInteger -Typ.

  • Ein Wert wird möglicherweise nicht roundtripen, wenn eine Gleitkommazahl beteiligt ist. Ein Wert wird als Roundtrip bezeichnet, wenn ein Vorgang eine ursprüngliche Gleitkommazahl in ein anderes Formular konvertiert, ein umgekehrter Vorgang das konvertierte Formular zurück in eine Gleitkommazahl umformt und die endgültige Gleitkommazahl gleich der ursprünglichen Gleitkommazahl ist. Der Roundtrip kann fehlschlagen, weil mindestens eine der am wenigsten signifikanten Ziffern bei einer Konvertierung verloren geht oder geändert wird. Im folgenden Beispiel werden drei Werte Single in Zeichenfolgen konvertiert und in einer Datei gespeichert. Wie die Ausgabe zeigt, sind die wiederhergestellten Werte, obwohl die Werte identisch zu sein scheinen, nicht gleich den ursprünglichen Werten.

    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Singles.dat");
          Single[] values = { 3.2f/1.11f, 1.0f/3f, (float) Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) {
             sw.Write(values[ctr].ToString());
             if (ctr != values.Length - 1)
                sw.Write("|");
          }      
          sw.Close();
          
          Single[] restoredValues = new Single[values.Length];
          StreamReader sr = new StreamReader(@".\Singles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Single.Parse(tempStrings[ctr]);   
    
          for (int ctr = 0; ctr < values.Length; ctr++)
             Console.WriteLine("{0} {2} {1}", values[ctr], 
                               restoredValues[ctr],
                               values[ctr].Equals(restoredValues[ctr]) ? "=" : "<>");
       }
    }
    // The example displays the following output:
    //       2.882883 <> 2.882883
    //       0.3333333 <> 0.3333333
    //       3.141593 <> 3.141593
    
    Imports System.IO
    
    Module Example
       Public Sub Main()
          Dim sw As New StreamWriter(".\Singles.dat")
          Dim values() As Single = { 3.2/1.11, 1.0/3, CSng(Math.PI)  }
          For ctr As Integer = 0 To values.Length - 1
             sw.Write(values(ctr).ToString())
             If ctr <> values.Length - 1 Then sw.Write("|")
          Next      
          sw.Close()
          
          Dim restoredValues(values.Length - 1) As Single
          Dim sr As New StreamReader(".\Singles.dat")
          Dim temp As String = sr.ReadToEnd()
          Dim tempStrings() As String = temp.Split("|"c)
          For ctr As Integer = 0 To tempStrings.Length - 1
             restoredValues(ctr) = Single.Parse(tempStrings(ctr))   
          Next 
    
          For ctr As Integer = 0 To values.Length - 1
             Console.WriteLine("{0} {2} {1}", values(ctr), 
                               restoredValues(ctr),
                               If(values(ctr).Equals(restoredValues(ctr)), "=", "<>"))
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '        2.882883 <> 2.882883
    '        0.3333333 <> 0.3333333
    '        3.141593 <> 3.141593
    

    In diesem Fall können die Werte erfolgreich mithilfe der numerischen Standardformatzeichenfolge "G9" gerundet werden, um die vollständige Genauigkeit der Werte zu erhalten, wie im folgenden Beispiel Single gezeigt.

    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Singles.dat");
          Single[] values = { 3.2f/1.11f, 1.0f/3f, (float) Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) 
             sw.Write("{0:G9}{1}", values[ctr], ctr < values.Length - 1 ? "|" : "" );
          
          sw.Close();
          
          Single[] restoredValues = new Single[values.Length];
          StreamReader sr = new StreamReader(@".\Singles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Single.Parse(tempStrings[ctr]);   
    
          for (int ctr = 0; ctr < values.Length; ctr++)
             Console.WriteLine("{0} {2} {1}", values[ctr], 
                               restoredValues[ctr],
                               values[ctr].Equals(restoredValues[ctr]) ? "=" : "<>");
       }
    }
    // The example displays the following output:
    //       2.882883 = 2.882883
    //       0.3333333 = 0.3333333
    //       3.141593 = 3.141593
    
    Imports System.IO
    
    Module Example
       Public Sub Main()
          Dim sw As New StreamWriter(".\Singles.dat")
          Dim values() As Single = { 3.2/1.11, 1.0/3, CSng(Math.PI)  }
          For ctr As Integer = 0 To values.Length - 1
             sw.Write("{0:G9}{1}", values(ctr), 
                      If(ctr < values.Length - 1, "|", ""))
          Next      
          sw.Close()
          
          Dim restoredValues(values.Length - 1) As Single
          Dim sr As New StreamReader(".\Singles.dat")
          Dim temp As String = sr.ReadToEnd()
          Dim tempStrings() As String = temp.Split("|"c)
          For ctr As Integer = 0 To tempStrings.Length - 1
             restoredValues(ctr) = Single.Parse(tempStrings(ctr))   
          Next 
    
          For ctr As Integer = 0 To values.Length - 1
             Console.WriteLine("{0} {2} {1}", values(ctr), 
                               restoredValues(ctr),
                               If(values(ctr).Equals(restoredValues(ctr)), "=", "<>"))
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       2.882883 = 2.882883
    '       0.3333333 = 0.3333333
    '       3.141593 = 3.141593
    
  • Single -Werte haben eine geringere Genauigkeit als Double -Werte. Ein Wert, der in ein scheinbar gleichwertiges konvertiert wird, entspricht aufgrund von Genauigkeitsunterschieden Single Double häufig nicht dem Double Wert. Im folgenden Beispiel wird das Ergebnis identischer Divisionsvorgänge einem Wert und Double einem Wert Single zugewiesen. Nachdem der Single Wert in einen -Wert umerwertet wurde, zeigt ein Vergleich der beiden Double Werte, dass sie ungleich sind.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 1/3.0;
          Single sValue2 = 1/3.0f;
          Double value2 = (Double) sValue2;
          Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2,
                                              value1.Equals(value2));
       }
    }
    // The example displays the following output:
    //        0.33333333333333331 = 0.3333333432674408: False
    
    Module Example
       Public Sub Main()
          Dim value1 As Double = 1/3
          Dim sValue2 As Single = 1/3
          Dim value2 As Double = CDbl(sValue2)
          Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2))
       End Sub
    End Module
    ' The example displays the following output:
    '       0.33333333333333331 = 0.3333333432674408: False
    

    Um dieses Problem zu vermeiden, verwenden Sie entweder den -Datentyp statt des -Datentyps, oder verwenden Sie die -Methode, damit beide Werte Double Single die gleiche Genauigkeit Round haben.

Testen auf Gleichheit

Um als gleich angesehen zu werden, müssen Single zwei Werte identische Werte darstellen. Aufgrund von Unterschieden bei der Genauigkeit zwischen Werten oder aufgrund eines Genauigkeitsverlusts um einen oder beide Werte stellen Gleitkommawerte, die als identisch erwartet werden, häufig aufgrund von Unterschieden in ihren am wenigsten signifikanten Ziffern als ungleich fest. Daher führen Aufrufe der -Methode, um zu bestimmen, ob zwei Werte gleich sind, oder Aufrufe der -Methode, um die Beziehung zwischen zwei Werten zu bestimmen, häufig Equals CompareTo zu Single unerwarteten Ergebnissen. Dies wird im folgenden Beispiel deutlich, bei dem zwei scheinbar gleiche Werte ungleich sind, da der erste Wert 7 Ziffern der Genauigkeit hat, während der zweite Wert Single 9 hat.

using System;

public class Example
{
   public static void Main()
   {
      float value1 = .3333333f;
      float value2 = 1.0f/3;
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
   }
}
// The example displays the following output:
//        0.3333333 = 0.333333343: False
Module Example
   Public Sub Main()
      Dim value1 As Single = .3333333
      Dim value2 As Single = 1/3
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2))
   End Sub
End Module
' The example displays the following output:
'       0.3333333 = 0.333333343: False

Berechnete Werte, die unterschiedlichen Codepfaden folgen und auf unterschiedliche Weise bearbeitet werden, erweisen sich häufig als ungleich. Im folgenden Beispiel ist ein Wert quadratisch, und dann wird die Quadratwurzel berechnet, Single um den ursprünglichen Wert wiederherzustellen. Eine Sekunde wird mit 3,51 multipliziert und quadratisch vor der Quadratwurzel des Ergebnisses durch 3,51 geteilt, um den ursprünglichen Single Wert wiederherzustellen. Obwohl die beiden Werte identisch zu sein scheinen, gibt ein Aufruf der -Methode Equals(Single) an, dass sie nicht gleich sind. Die Verwendung der Standardformatzeichenfolge "G9" zum Zurückgeben einer Ergebniszeichenfolge, die alle signifikanten Ziffern jedes Werts anzeigt, zeigt, dass der zweite Wert .0000000000001 kleiner als der erste Single wert ist.

using System;

public class Example
{
   public static void Main()
   {
      float value1 = 10.201438f;
      value1 = (float) Math.Sqrt((float) Math.Pow(value1, 2));
      float value2 = (float) Math.Pow((float) value1 * 3.51f, 2);
      value2 = ((float) Math.Sqrt(value2)) / 3.51f;
      Console.WriteLine("{0} = {1}: {2}\n", 
                        value1, value2, value1.Equals(value2)); 
      Console.WriteLine("{0:G9} = {1:G9}", value1, value2); 
   }
}
// The example displays the following output:
//       10.20144 = 10.20144: False
//       
//       10.201438 = 10.2014389
Module Example
   Public Sub Main()
      Dim value1 As Single = 10.201438
      value1 = CSng(Math.Sqrt(CSng(Math.Pow(value1, 2))))
      Dim value2 As Single = CSng(Math.Pow(value1 * CSng(3.51), 2))
      value2 = CSng(Math.Sqrt(value2) / CSng(3.51))
      Console.WriteLine("{0} = {1}: {2}", 
                        value1, value2, value1.Equals(value2)) 
      Console.WriteLine()
      Console.WriteLine("{0:G9} = {1:G9}", value1, value2) 
   End Sub
End Module
' The example displays the following output:
'       10.20144 = 10.20144: False
'       
'       10.201438 = 10.2014389

In Fällen, in denen sich ein Genauigkeitsverlust wahrscheinlich auf das Ergebnis eines Vergleichs auswirken wird, können Sie die folgenden Techniken verwenden, anstatt die - oder Equals -Methode CompareTo auf aufruft:

  • Rufen Sie die Math.Round -Methode auf, um sicherzustellen, dass beide Werte die gleiche Genauigkeit haben. Im folgenden Beispiel wird ein vorheriges Beispiel so modifiziert, dass dieser Ansatz so verwendet wird, dass zwei Bruchwerte gleichwertig sind.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float value1 = .3333333f;
          float value2 = 1.0f/3;
          int precision = 7;
          value1 = (float) Math.Round(value1, precision);
          value2 = (float) Math.Round(value2, precision);
          Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
       }
    }
    // The example displays the following output:
    //        0.3333333 = 0.3333333: True
    
    Module Example
       Public Sub Main()
          Dim value1 As Single = .3333333
          Dim value2 As Single = 1/3
          Dim precision As Integer = 7
          value1 = CSng(Math.Round(value1, precision))
          value2 = CSng(Math.Round(value2, precision))
          Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2))
       End Sub
    End Module
    ' The example displays the following output:
    '       0.3333333 = 0.3333333: True
    

    Das Problem der Genauigkeit gilt weiterhin für die Rundung von Mittelpunktwerten. Weitere Informationen finden Sie unter der Methode Math.Round(Double, Int32, MidpointRounding).

  • Testen Sie auf ungefähre Gleichheit anstelle von Gleichheit. Diese Technik erfordert, dass Sie entweder einen absoluten Betrag definieren, um den sich die beiden Werte unterscheiden können, aber trotzdem gleich sind, oder dass Sie einen relativen Betrag definieren, um den der kleinere Wert vom größeren Wert abweichen kann.

    Warnung

    Single.Epsilon wird manchmal als absolutes Maß für den Abstand zwischen zwei Werten Single verwendet, wenn auf Gleichheit getestet wird. Misst jedoch den kleinsten möglichen Wert, der hinzugefügt oder von einem subtrahiert werden kann, dessen Wert Single.Epsilon Single 0 (null) ist. Für die meisten positiven und negativen Single Werte ist der Wert von zu Single.Epsilon klein, um erkannt zu werden. Daher wird mit Ausnahme von Werten, die null sind, die Verwendung in Gleichheitstests nicht empfohlen.

    Im folgenden Beispiel wird der zweite Ansatz verwendet, um eine Methode IsApproximatelyEqual zu definieren, die den relativen Unterschied zwischen zwei Werten testet. Sie vergleicht auch das Ergebnis von Aufrufen der IsApproximatelyEqual -Methode und der Equals(Single) -Methode.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float one1 = .1f * 10;
          float one2 = 0f;
          for (int ctr = 1; ctr <= 10; ctr++)
             one2 += .1f;
    
          Console.WriteLine("{0:R} = {1:R}: {2}", one1, one2, one1.Equals(one2));
          Console.WriteLine("{0:R} is approximately equal to {1:R}: {2}", 
                            one1, one2, 
                            IsApproximatelyEqual(one1, one2, .000001f));   
       }
    
       static bool IsApproximatelyEqual(float value1, float value2, float epsilon)
       {
          // If they are equal anyway, just return True.
          if (value1.Equals(value2))
             return true;
    
          // Handle NaN, Infinity.
          if (Double.IsInfinity(value1) | Double.IsNaN(value1))
             return value1.Equals(value2);
          else if (Double.IsInfinity(value2) | Double.IsNaN(value2))
             return value1.Equals(value2);
    
          // Handle zero to avoid division by zero
          double divisor = Math.Max(value1, value2);
          if (divisor.Equals(0)) 
             divisor = Math.Min(value1, value2);
          
          return Math.Abs(value1 - value2)/divisor <= epsilon;           
       } 
    }
    // The example displays the following output:
    //       1 = 1.00000012: False
    //       1 is approximately equal to 1.00000012: True
    
    Module Example
       Public Sub Main()
          Dim one1 As Single = .1 * 10
          Dim one2 As Single = 0
          For ctr As Integer = 1 To 10
             one2 += CSng(.1)
          Next
          Console.WriteLine("{0:R} = {1:R}: {2}", one1, one2, one1.Equals(one2))
          Console.WriteLine("{0:R} is approximately equal to {1:R}: {2}", 
                            one1, one2, 
                            IsApproximatelyEqual(one1, one2, .000001))   
       End Sub
    
       Function IsApproximatelyEqual(value1 As Single, value2 As Single, 
                                     epsilon As Single) As Boolean
          ' If they are equal anyway, just return True.
          If value1.Equals(value2) Then Return True
          
          ' Handle NaN, Infinity.
          If Single.IsInfinity(value1) Or Single.IsNaN(value1) Then
             Return value1.Equals(value2)
          Else If Single.IsInfinity(value2) Or Single.IsNaN(value2)
             Return value1.Equals(value2)
          End If
          
          ' Handle zero to avoid division by zero
          Dim divisor As Single = Math.Max(value1, value2)
          If divisor.Equals(0) Then
             divisor = Math.Min(value1, value2)
          End If 
          
          Return Math.Abs(value1 - value2)/divisor <= epsilon           
       End Function
    End Module
    ' The example displays the following output:
    '       1 = 1.00000012: False
    '       1 is approximately equal to 1.00000012: True
    

Gleitkommawerte und Ausnahmen

Vorgänge mit Gleitkommawerten auslösen keine Ausnahmen, im Gegensatz zu Vorgängen mit integralen Typen, die Ausnahmen bei unzulässigen Vorgängen auslösen, z. B. Division durch 0 (null) oder Überlauf. Stattdessen ist in diesen Situationen das Ergebnis eines Gleitkomma-Vorgangs null, positiv unendlich, negativ unendlich oder keine Zahl (NaN):

  • Wenn das Ergebnis eines Gleitkomma-Vorgangs zu klein für das Zielformat ist, ist das Ergebnis 0 (null). Dies kann auftreten, wenn zwei sehr kleine Gleitkommazahlen multipliziert werden, wie im folgenden Beispiel gezeigt.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float value1 = 1.163287e-36f;
          float value2 = 9.164234e-25f;
          float result = value1 * value2;
          Console.WriteLine("{0} * {1} = {2}", value1, value2, result);
          Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0f));
       }
    }
    // The example displays the following output:
    //       1.163287E-36 * 9.164234E-25 = 0
    //       0 = 0: True
    
    Module Example
       Public Sub Main()
          Dim value1 As Single = 1.163287e-36
          Dim value2 As Single = 9.164234e-25
          Dim result As Single = value1 * value2
          Console.WriteLine("{0} * {1} = {2:R}", value1, value2, result)
          Console.WriteLine("{0} = 0: {1}", result, result.Equals(0))
       End Sub
    End Module
    ' The example displays the following output:
    '       1.163287E-36 * 9.164234E-25 = 0
    '       0 = 0: True
    
  • Wenn die Größe des Ergebnisses eines Gleitkommavorgang den Bereich des Zielformats überschreitet, ist das Ergebnis des Vorgangs oder , entsprechend dem Vorzeichen des PositiveInfinity NegativeInfinity Ergebnisses. Das Ergebnis eines Vorgangs, bei dem ein Überlauf auftritt, ist , und das Ergebnis eines Single.MaxValue Überlaufs ist , wie im folgenden Beispiel PositiveInfinity Single.MinValue NegativeInfinity gezeigt.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float value1 = 3.065e35f;
          float value2 = 6.9375e32f;
          float result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Single.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}\n", 
                            Single.IsNegativeInfinity(result));
    
          value1 = -value1;
          result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Single.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}", 
                            Single.IsNegativeInfinity(result));
       }
    }                                                                 
    
    // The example displays the following output:
    //       PositiveInfinity: True
    //       NegativeInfinity: False
    //       
    //       PositiveInfinity: False
    //       NegativeInfinity: True
    
    Module Example
       Public Sub Main()
          Dim value1 As Single = 3.065e35
          Dim value2 As Single = 6.9375e32
          Dim result As Single = value1 * value2
          Console.WriteLine("PositiveInfinity: {0}", 
                             Single.IsPositiveInfinity(result))
          Console.WriteLine("NegativeInfinity: {0}", 
                            Single.IsNegativeInfinity(result))
          Console.WriteLine()                  
          value1 = -value1
          result = value1 * value2
          Console.WriteLine("PositiveInfinity: {0}", 
                             Single.IsPositiveInfinity(result))
          Console.WriteLine("NegativeInfinity: {0}", 
                            Single.IsNegativeInfinity(result))
       End Sub
    End Module
    ' The example displays the following output:
    '       PositiveInfinity: True
    '       NegativeInfinity: False
    '       
    '       PositiveInfinity: False
    '       NegativeInfinity: True
    

    PositiveInfinity resultiert auch aus einer Division durch 0 (null) mit einem positiven Dividend und ergibt sich aus einer Division NegativeInfinity durch 0 (null) mit einem negativen Dividend.

  • Wenn ein Gleitkommavorgang ungültig ist, ist das Ergebnis des Vorgangs NaN . Dies ergibt NaN sich beispielsweise aus den folgenden Vorgängen:

    • Division durch 0 (null) mit einem Dividend von 0 (null). Beachten Sie, dass andere Fälle der Division durch 0 (null) entweder oder PositiveInfinity NegativeInfinity ergeben.

    • Jeder Gleitkommavorgang mit ungültiger Eingabe. Wenn Sie beispielsweise versuchen, die Quadratwurzel eines negativen Werts zu finden, wird NaN zurückgegeben.

    • Jeder Vorgang mit einem Argument, dessen Wert Single.NaN ist.

Typkonvertierungen und die einzelne Struktur

Die Single -Struktur definiert keine expliziten oder impliziten Konvertierungsoperatoren. Stattdessen werden Konvertierungen vom Compiler implementiert.

In der folgenden Tabelle sind die möglichen Konvertierungen eines Werts der anderen primitiven numerischen Typen in einen -Wert aufgeführt. Sie gibt auch an, ob die Konvertierung sich ausweitend oder einengt und ob die resultierende möglicherweise eine geringere Genauigkeit als der ursprüngliche Wert Single Single hat.

Konvertierung von Widening/Narrowing Möglicher Genauigkeitsverlust
Byte Widening Nein
Decimal Widening

Beachten Sie, dass C# einen Umwandlungsoperator erfordert.
Ja. Decimal unterstützt 29 Dezimalstellen mit Genauigkeit. Single unterstützt 9.
Double Eingrenzend; Werte außerhalb des Bereichs werden in Double.NegativeInfinity oder Double.PositiveInfinity konvertiert. Ja. Double unterstützt 17 Dezimalstellen mit Genauigkeit. Single unterstützt 9.
Int16 Widening Nein
Int32 Widening Ja. Int32 unterstützt 10 Dezimalstellen mit Genauigkeit. Single unterstützt 9.
Int64 Widening Ja. Int64 unterstützt 19 Dezimalstellen mit Genauigkeit. Single unterstützt 9.
SByte Widening Nein
UInt16 Widening Nein
UInt32 Widening Ja. UInt32 unterstützt 10 Dezimalstellen mit Genauigkeit. Single unterstützt 9.
UInt64 Widening Ja. Int64 unterstützt 20 Dezimalstellen mit Genauigkeit. Single unterstützt 9.

Im folgenden Beispiel wird der Mindest- oder Höchstwert anderer primitiver numerischer Typen in einen Single -Wert konvertiert.

using System;

public class Example
{
   public static void Main()
   {
      dynamic[] values = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
                           Decimal.MaxValue, Double.MinValue, Double.MaxValue,
                           Int16.MinValue, Int16.MaxValue, Int32.MinValue,
                           Int32.MaxValue, Int64.MinValue, Int64.MaxValue,
                           SByte.MinValue, SByte.MaxValue, UInt16.MinValue,
                           UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
                           UInt64.MinValue, UInt64.MaxValue };
      float sngValue;
      foreach (var value in values) {
         if (value.GetType() == typeof(Decimal) ||
             value.GetType() == typeof(Double))
            sngValue = (float) value;
         else
            sngValue = value;
         Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
                           value, value.GetType().Name,
                           sngValue, sngValue.GetType().Name);
      }
   }
}
// The example displays the following output:
//       0 (Byte) --> 0 (Single)
//       255 (Byte) --> 255 (Single)
//       -79228162514264337593543950335 (Decimal) --> -7.92281625E+28 (Single)
//       79228162514264337593543950335 (Decimal) --> 7.92281625E+28 (Single)
//       -1.79769313486232E+308 (Double) --> -Infinity (Single)
//       1.79769313486232E+308 (Double) --> Infinity (Single)
//       -32768 (Int16) --> -32768 (Single)
//       32767 (Int16) --> 32767 (Single)
//       -2147483648 (Int32) --> -2.14748365E+09 (Single)
//       2147483647 (Int32) --> 2.14748365E+09 (Single)
//       -9223372036854775808 (Int64) --> -9.223372E+18 (Single)
//       9223372036854775807 (Int64) --> 9.223372E+18 (Single)
//       -128 (SByte) --> -128 (Single)
//       127 (SByte) --> 127 (Single)
//       0 (UInt16) --> 0 (Single)
//       65535 (UInt16) --> 65535 (Single)
//       0 (UInt32) --> 0 (Single)
//       4294967295 (UInt32) --> 4.2949673E+09 (Single)
//       0 (UInt64) --> 0 (Single)
//       18446744073709551615 (UInt64) --> 1.84467441E+19 (Single)
Module Example
   Public Sub Main()
      Dim values() As Object = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
                                 Decimal.MaxValue, Double.MinValue, Double.MaxValue,
                                 Int16.MinValue, Int16.MaxValue, Int32.MinValue,
                                 Int32.MaxValue, Int64.MinValue, Int64.MaxValue,
                                 SByte.MinValue, SByte.MaxValue, UInt16.MinValue,
                                 UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
                                 UInt64.MinValue, UInt64.MaxValue }
      Dim sngValue As Single
      For Each value In values
         If value.GetType() = GetType(Double) Then
            sngValue = CSng(value)
         Else
            sngValue = value
         End If
         Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
                           value, value.GetType().Name,
                           sngValue, sngValue.GetType().Name)
      Next
   End Sub
End Module
' The example displays the following output:
'       0 (Byte) --> 0 (Single)
'       255 (Byte) --> 255 (Single)
'       -79228162514264337593543950335 (Decimal) --> -7.92281625E+28 (Single)
'       79228162514264337593543950335 (Decimal) --> 7.92281625E+28 (Single)
'       -1.79769313486232E+308 (Double) --> -Infinity (Single)
'       1.79769313486232E+308 (Double) --> Infinity (Single)
'       -32768 (Int16) --> -32768 (Single)
'       32767 (Int16) --> 32767 (Single)
'       -2147483648 (Int32) --> -2.14748365E+09 (Single)
'       2147483647 (Int32) --> 2.14748365E+09 (Single)
'       -9223372036854775808 (Int64) --> -9.223372E+18 (Single)
'       9223372036854775807 (Int64) --> 9.223372E+18 (Single)
'       -128 (SByte) --> -128 (Single)
'       127 (SByte) --> 127 (Single)
'       0 (UInt16) --> 0 (Single)
'       65535 (UInt16) --> 65535 (Single)
'       0 (UInt32) --> 0 (Single)
'       4294967295 (UInt32) --> 4.2949673E+09 (Single)
'       0 (UInt64) --> 0 (Single)
'       18446744073709551615 (UInt64) --> 1.84467441E+19 (Single)

Darüber hinaus werden die Double Werte , und in , Double.NaN Double.PositiveInfinity Double.NegativeInfinity Single.NaN Single.PositiveInfinity Single.NegativeInfinity bzw. konvertiert.

Beachten Sie, dass die Konvertierung des Werts einiger numerischer Typen in einen Single Wert zu einem Genauigkeitsverlust führen kann. Wie das Beispiel veranschaulicht, ist ein Genauigkeitsverlust möglich, wenn werte , , , , und in -Werte konvertiert Decimal Double Int32 Int64 UInt32 UInt64 Single werden.

Die Konvertierung eines Single Werts in eine Double ist eine erweiternde Konvertierung. Die Konvertierung kann zu einem Genauigkeitsverlust führen, wenn der Double Typ keine genaue Darstellung für den Wert Single hat.

Die Konvertierung eines Single Werts in einen Wert eines beliebigen primitiven numerischen Datentyps außer ist Double eine einschränkende Konvertierung und erfordert einen Umwandlungsoperator (in C#) oder eine Konvertierungsmethode (in Visual Basic). Werte, die sich außerhalb des Bereichs des Zieldatentyps befinden, die durch die Eigenschaften und des Zieltyps definiert MinValue MaxValue werden, verhalten sich wie in der folgenden Tabelle dargestellt.

Zieltyp Ergebnis
Beliebiger ganzzahligen Typ Eine OverflowException Ausnahme, wenn die Konvertierung in einem überprüften Kontext erfolgt.

Wenn die Konvertierung in einem nicht überprüften Kontext erfolgt (standard in C#), ist der Konvertierungsvorgang erfolgreich, aber der Wert überläuft.
Decimal Eine OverflowException Ausnahme,

Darüber hinaus Single.NaN löst , und eine für Single.PositiveInfinity Single.NegativeInfinity OverflowException Konvertierungen in ganze Zahlen in einem überprüften Kontext aus, aber diese Werte überlaufen, wenn sie in einen nicht überprüften Kontext in ganze Zahlen konvertiert werden. Bei Konvertierungen in Decimal wird immer eine OverflowException ausgelöst. Konvertierung in Double, sie konvertieren in Double.NaN, Double.PositiveInfinity, und Double.NegativeInfinitybzw.

Beachten Sie, dass ein Genauigkeitsverlust durch die Konvertierung eines Single Werts in einen anderen numerischen Typ entstehen kann. Bei der Konvertierung von nicht ganzzahligen Werten geht die Single Bruchkomponente verloren, wenn der Single Wert gerundet (wie in Visual Basic) oder abgeschnitten wird (wie in C#). Bei Konvertierungen in Werte weist Decimal der Wert möglicherweise keine genaue Darstellung im Single Zieldatentyp auf.

Im folgenden Beispiel wird eine Reihe von Single Werten in mehrere andere numerische Typen konvertiert. Die Konvertierungen erfolgen in einem überprüften Kontext in Visual Basic (Standardeinstellung) und in C# (aufgrund des checked-Schlüsselworts). Die Ausgabe des Beispiels zeigt das Ergebnis für Konvertierungen in einem überprüften und nicht überprüften Kontext. Sie können Konvertierungen in einem nicht überprüften Kontext in Visual Basic ausführen, indem Sie mit dem Compilerschalter kompilieren /removeintchecks+ und in C# die checked -Anweisung auskommentieren.

using System;

public class Example
{
   public static void Main()
   {
      float[] values = { Single.MinValue, -67890.1234f, -12345.6789f,
                         12345.6789f, 67890.1234f, Single.MaxValue,
                         Single.NaN, Single.PositiveInfinity,
                         Single.NegativeInfinity };
      checked {
         foreach (var value in values) {
            try {
                Int64 lValue = (long) value;
                Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
                                  value, value.GetType().Name,
                                  lValue, lValue.GetType().Name);
            }
            catch (OverflowException) {
               Console.WriteLine("Unable to convert {0} to Int64.", value);
            }
            try {
                UInt64 ulValue = (ulong) value;
                Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
                                  value, value.GetType().Name,
                                  ulValue, ulValue.GetType().Name);
            }
            catch (OverflowException) {
               Console.WriteLine("Unable to convert {0} to UInt64.", value);
            }
            try {
                Decimal dValue = (decimal) value;
                Console.WriteLine("{0} ({1}) --> {2} ({3})",
                                  value, value.GetType().Name,
                                  dValue, dValue.GetType().Name);
            }
            catch (OverflowException) {
               Console.WriteLine("Unable to convert {0} to Decimal.", value);
            }

            Double dblValue = value;
            Console.WriteLine("{0} ({1}) --> {2} ({3})",
                              value, value.GetType().Name,
                              dblValue, dblValue.GetType().Name);
            Console.WriteLine();
         }
      }
   }
}
// The example displays the following output for conversions performed
// in a checked context:
//       Unable to convert -3.402823E+38 to Int64.
//       Unable to convert -3.402823E+38 to UInt64.
//       Unable to convert -3.402823E+38 to Decimal.
//       -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
//
//       -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       Unable to convert -67890.13 to UInt64.
//       -67890.13 (Single) --> -67890.12 (Decimal)
//       -67890.13 (Single) --> -67890.125 (Double)
//
//       -12345.68 (Single) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       Unable to convert -12345.68 to UInt64.
//       -12345.68 (Single) --> -12345.68 (Decimal)
//       -12345.68 (Single) --> -12345.6787109375 (Double)
//
//       12345.68 (Single) --> 12345 (0x0000000000003039) (Int64)
//       12345.68 (Single) --> 12345 (0x0000000000003039) (UInt64)
//       12345.68 (Single) --> 12345.68 (Decimal)
//       12345.68 (Single) --> 12345.6787109375 (Double)
//
//       67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
//       67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
//       67890.13 (Single) --> 67890.12 (Decimal)
//       67890.13 (Single) --> 67890.125 (Double)
//
//       Unable to convert 3.402823E+38 to Int64.
//       Unable to convert 3.402823E+38 to UInt64.
//       Unable to convert 3.402823E+38 to Decimal.
//       3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
//
//       Unable to convert NaN to Int64.
//       Unable to convert NaN to UInt64.
//       Unable to convert NaN to Decimal.
//       NaN (Single) --> NaN (Double)
//
//       Unable to convert Infinity to Int64.
//       Unable to convert Infinity to UInt64.
//       Unable to convert Infinity to Decimal.
//       Infinity (Single) --> Infinity (Double)
//
//       Unable to convert -Infinity to Int64.
//       Unable to convert -Infinity to UInt64.
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Single) --> -Infinity (Double)
// The example displays the following output for conversions performed
// in an unchecked context:
//       -3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -3.402823E+38 (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -3.402823E+38 to Decimal.
//       -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
//
//       -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       -67890.13 (Single) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
//       -67890.13 (Single) --> -67890.12 (Decimal)
//       -67890.13 (Single) --> -67890.125 (Double)
//
//       -12345.68 (Single) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       -12345.68 (Single) --> 18446744073709539271 (0xFFFFFFFFFFFFCFC7) (UInt64)
//       -12345.68 (Single) --> -12345.68 (Decimal)
//       -12345.68 (Single) --> -12345.6787109375 (Double)
//
//       12345.68 (Single) --> 12345 (0x0000000000003039) (Int64)
//       12345.68 (Single) --> 12345 (0x0000000000003039) (UInt64)
//       12345.68 (Single) --> 12345.68 (Decimal)
//       12345.68 (Single) --> 12345.6787109375 (Double)
//
//       67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
//       67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
//       67890.13 (Single) --> 67890.12 (Decimal)
//       67890.13 (Single) --> 67890.125 (Double)
//
//       3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       3.402823E+38 (Single) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert 3.402823E+38 to Decimal.
//       3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
//
//       NaN (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       NaN (Single) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert NaN to Decimal.
//       NaN (Single) --> NaN (Double)
//
//       Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       Infinity (Single) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert Infinity to Decimal.
//       Infinity (Single) --> Infinity (Double)
//
//       -Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -Infinity (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Single) --> -Infinity (Double)
Module Example
   Public Sub Main()
      Dim values() As Single = { Single.MinValue, -67890.1234, -12345.6789,
                                 12345.6789, 67890.1234, Single.MaxValue,
                                 Single.NaN, Single.PositiveInfinity,
                                 Single.NegativeInfinity }
      For Each value In values
         Try
             Dim lValue As Long = CLng(value)
             Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
                               value, value.GetType().Name,
                               lValue, lValue.GetType().Name)
         Catch e As OverflowException
            Console.WriteLine("Unable to convert {0} to Int64.", value)
         End Try
         Try
             Dim ulValue As UInt64 = CULng(value)
             Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
                               value, value.GetType().Name,
                               ulValue, ulValue.GetType().Name)
         Catch e As OverflowException
            Console.WriteLine("Unable to convert {0} to UInt64.", value)
         End Try
         Try
             Dim dValue As Decimal = CDec(value)
             Console.WriteLine("{0} ({1}) --> {2} ({3})",
                               value, value.GetType().Name,
                               dValue, dValue.GetType().Name)
         Catch e As OverflowException
            Console.WriteLine("Unable to convert {0} to Decimal.", value)
         End Try

         Dim dblValue As Double = value
         Console.WriteLine("{0} ({1}) --> {2} ({3})",
                           value, value.GetType().Name,
                           dblValue, dblValue.GetType().Name)
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output for conversions performed
' in a checked context:
'       Unable to convert -3.402823E+38 to Int64.
'       Unable to convert -3.402823E+38 to UInt64.
'       Unable to convert -3.402823E+38 to Decimal.
'       -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
'
'       -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
'       Unable to convert -67890.13 to UInt64.
'       -67890.13 (Single) --> -67890.12 (Decimal)
'       -67890.13 (Single) --> -67890.125 (Double)
'
'       -12345.68 (Single) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64)
'       Unable to convert -12345.68 to UInt64.
'       -12345.68 (Single) --> -12345.68 (Decimal)
'       -12345.68 (Single) --> -12345.6787109375 (Double)
'
'       12345.68 (Single) --> 12346 (0x000000000000303A) (Int64)
'       12345.68 (Single) --> 12346 (0x000000000000303A) (UInt64)
'       12345.68 (Single) --> 12345.68 (Decimal)
'       12345.68 (Single) --> 12345.6787109375 (Double)
'
'       67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
'       67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
'       67890.13 (Single) --> 67890.12 (Decimal)
'       67890.13 (Single) --> 67890.125 (Double)
'
'       Unable to convert 3.402823E+38 to Int64.
'       Unable to convert 3.402823E+38 to UInt64.
'       Unable to convert 3.402823E+38 to Decimal.
'       3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
'
'       Unable to convert NaN to Int64.
'       Unable to convert NaN to UInt64.
'       Unable to convert NaN to Decimal.
'       NaN (Single) --> NaN (Double)
'
'       Unable to convert Infinity to Int64.
'       Unable to convert Infinity to UInt64.
'       Unable to convert Infinity to Decimal.
'       Infinity (Single) --> Infinity (Double)
'
'       Unable to convert -Infinity to Int64.
'       Unable to convert -Infinity to UInt64.
'       Unable to convert -Infinity to Decimal.
'       -Infinity (Single) --> -Infinity (Double)
' The example displays the following output for conversions performed
' in an unchecked context:
'       -3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       -3.402823E+38 (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
'       Unable to convert -3.402823E+38 to Decimal.
'       -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
'
'       -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
'       -67890.13 (Single) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
'       -67890.13 (Single) --> -67890.12 (Decimal)
'       -67890.13 (Single) --> -67890.125 (Double)
'
'       -12345.68 (Single) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64)
'       -12345.68 (Single) --> 18446744073709539270 (0xFFFFFFFFFFFFCFC6) (UInt64)
'       -12345.68 (Single) --> -12345.68 (Decimal)
'       -12345.68 (Single) --> -12345.6787109375 (Double)
'
'       12345.68 (Single) --> 12346 (0x000000000000303A) (Int64)
'       12345.68 (Single) --> 12346 (0x000000000000303A) (UInt64)
'       12345.68 (Single) --> 12345.68 (Decimal)
'       12345.68 (Single) --> 12345.6787109375 (Double)
'
'       67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
'       67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
'       67890.13 (Single) --> 67890.12 (Decimal)
'       67890.13 (Single) --> 67890.125 (Double)
'
'       3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       3.402823E+38 (Single) --> 0 (0x0000000000000000) (UInt64)
'       Unable to convert 3.402823E+38 to Decimal.
'       3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
'
'       NaN (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       NaN (Single) --> 0 (0x0000000000000000) (UInt64)
'       Unable to convert NaN to Decimal.
'       NaN (Single) --> NaN (Double)
'
'       Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       Infinity (Single) --> 0 (0x0000000000000000) (UInt64)
'       Unable to convert Infinity to Decimal.
'       Infinity (Single) --> Infinity (Double)
'
'       -Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       -Infinity (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
'       Unable to convert -Infinity to Decimal.
'       -Infinity (Single) --> -Infinity (Double)

Weitere Informationen zur Konvertierung numerischer Typen finden Sie unter Typkonvertierung in den Tabellen .NET Framework und Typkonvertierung.

Gleitkommafunktionen

Die Single Struktur und die zugehörigen Typen stellen Methoden zum Ausführen der folgenden Kategorien von Vorgängen bereit:

  • Vergleich der Werte. Sie können die Equals -Methode aufrufen, um zu bestimmen, ob zwei Single Werte gleich sind, oder die CompareTo -Methode, um die Beziehung zwischen zwei Werten zu bestimmen.

    Die Single -Struktur unterstützt auch einen vollständigen Satz von Vergleichsoperatoren. Beispielsweise können Sie auf Gleichheit oder Ungleichheit testen oder bestimmen, ob ein Wert größer oder gleich einem anderen Wert ist. Wenn einer der Operanden ein Double ist, wird der Single Wert vor dem Vergleich in ein Double konvertiert. Wenn einer der Operanden ein integraler Typ ist, wird er vor dem Vergleich in ein Single konvertiert. Obwohl es sich hierbei um erweiternde Konvertierungen handelt, kann es zu einem Genauigkeitsverlust kommen.

    Warnung

    Aufgrund von Genauigkeitsunterschieden können sich zwei Werte, von denen Single Sie erwarten, dass sie gleich sind, als ungleich erweisen, was sich auf das Ergebnis des Vergleichs auswirkt. Weitere Informationen zum Vergleichen von zwei Werten finden Sie im Abschnitt Testen auf Single Gleichheit.

    Sie können auch die IsNaN Methoden , , und IsInfinity IsPositiveInfinity IsNegativeInfinity aufrufen, um diese speziellen Werte zu testen.

  • Mathematische Operationen. Allgemeine arithmetische Operationen wie Addition, Subtraktion, Multiplikation und Division werden von Sprachcompilern und CIL-Anweisungen (Common Intermediate Language) anstelle von Single Methoden implementiert. Wenn der andere Operand in einer mathematischen Operation ein Double ist, Single wird der vor dem Ausführen des Vorgangs in einen Double konvertiert, und das Ergebnis des Vorgangs ist ebenfalls ein Double -Wert. Wenn der andere Operand ein integraler Typ ist, wird er vor dem Ausführen des Vorgangs in einen Single konvertiert, und das Ergebnis des Vorgangs ist ebenfalls ein Single Wert.

    Sie können andere mathematische Operationen ausführen, indem Sie static ( Shared in Visual Basic) Methoden in der System.Math -Klasse aufrufen. Dazu gehören zusätzliche Methoden, die häufig für arithmetische (z. B. Math.Abs , und ), Geometrie Math.Sign Math.Sqrt (z. B. Math.Cos und ) und Math.Sin Berechnungen (z. Math.Log B. ) verwendet werden. In allen Fällen wird der Single Wert in einen Double konvertiert.

    Sie können auch die einzelnen Bits in einem Single Wert bearbeiten. Die BitConverter.GetBytes(Single) -Methode gibt ihr Bitmuster in einem Bytearray zurück. Indem Sie dieses Bytearray an die BitConverter.ToInt32 -Methode übergeben, können Sie auch das Single Bitmuster des Werts in einer 32-Bit-Ganzzahl beibehalten.

  • Rundung von. Rundung wird häufig als Technik verwendet, um die Auswirkungen von Unterschieden zwischen Werten zu verringern, die durch Probleme bei gleitkommabasierter Darstellung und Genauigkeit verursacht werden. Sie können einen Single Wert runden, indem Sie die Math.Round -Methode aufrufen. Beachten Sie jedoch, dass der Single Wert in einen konvertiert Double wird, bevor die -Methode aufgerufen wird, und dass die Konvertierung einen Genauigkeitsverlust mit sich bringen kann.

  • Formatieren von . Sie können einen Wert in seine Zeichenfolgendarstellung konvertieren, Single indem Sie die ToString -Methode aufrufen oder das Feature für die zusammengesetzte Formatierung verwenden. Informationen dazu, wie Formatzeichenfolgen die Zeichenfolgendarstellung von Gleitkommawerten steuern, finden Sie in den Themen Standardmäßige numerische Formatzeichenfolgen und Benutzerdefinierte numerische Formatzeichenfolgen.

  • Analysieren von Zeichenfolgen. Sie können die Zeichenfolgendarstellung eines Gleitkommawerts in einen Wert konvertieren, Single indem Sie die - oder Parse TryParse -Methode aufrufen. Wenn der Analysevorgang fehlschlägt, löst die Parse Methode eine Ausnahme aus, während die Methode TryParse false zurückgibt.

  • Typkonvertierung. Die Single -Struktur stellt eine explizite Schnittstellenimplementierung für die IConvertible -Schnittstelle bereit, die die Konvertierung zwischen zwei standard .NET Framework Datentypen unterstützt. Sprachcompiler unterstützen auch die implizite Konvertierung von Werten für alle anderen numerischen Standardtypen mit Ausnahme der Konvertierung von Double in Single -Werte. Die Konvertierung eines Werts eines beliebigen numerischen Standardtyps als in Double eine Single ist eine erweiternde Konvertierung und erfordert nicht die Verwendung eines Umwandlungsoperators oder einer Konvertierungsmethode.

    Die Konvertierung von 32-Bit- und 64-Bit-Ganzzahlwerten kann jedoch zu einem Genauigkeitsverlust führen. In der folgenden Tabelle sind die Unterschiede bei der Genauigkeit für 32-Bit-, 64-Bit- und Double -Typen aufgeführt:

    Typ Maximale Genauigkeit (in Dezimalstellen) Interne Genauigkeit (in Dezimalstellen)
    Double 15 17
    Int32 und UInt32 10 10
    Int64 und UInt64 19 19
    Single 7 9

    Das Problem der Genauigkeit wirkt sich am häufigsten auf Single Werte aus, die in -Werte konvertiert Double werden. Im folgenden Beispiel sind zwei Werte, die von identischen Divisionsvorgängen erzeugt werden, ungleich, da einer der -Werte ein Gleitkommawert mit einfacher Genauigkeit ist, der in einen konvertiert Double wird.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 1/3.0;
          Single sValue2 = 1/3.0f;
          Double value2 = (Double) sValue2;
          Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, 
                                              value1.Equals(value2));
       }
    }
    // The example displays the following output:
    //        0.33333333333333331 = 0.3333333432674408: False
    
    Module Example
       Public Sub Main()
          Dim value1 As Double = 1/3
          Dim sValue2 As Single = 1/3
          Dim value2 As Double = CDbl(sValue2)
          Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2))
       End Sub
    End Module
    ' The example displays the following output:
    '       0.33333333333333331 = 0.3333333432674408: False
    

Felder

Epsilon

Stellt den kleinsten positiven Single-Wert dar, der größer als 0 (null) ist. Dieses Feld ist konstant.

MaxValue

Stellt den größtmöglichen Wert von Single dar. Dieses Feld ist konstant.

MinValue

Stellt den kleinstmöglichen Wert von Single dar. Dieses Feld ist konstant.

NaN

Stellt Not-a-Number (NaN) dar. Dieses Feld ist konstant.

NegativeInfinity

Stellt minus unendlich dar. Dieses Feld ist konstant.

PositiveInfinity

Stellt plus unendlich dar. Dieses Feld ist konstant.

Methoden

CompareTo(Object)

Vergleicht diese Instanz mit einem angegebenen Objekt und gibt eine ganze Zahl zurück, die angibt, ob der Wert dieser Instanz kleiner oder größer als der Wert des angegebenen Objekts ist oder mit diesem übereinstimmt.

CompareTo(Single)

Vergleicht diese Instanz mit einer angegebenen Gleitkommazahl mit einfacher Genauigkeit und gibt eine ganze Zahl zurück, die angibt, ob der Wert dieser Instanz kleiner oder größer als der Wert der angegebenen Gleitkommazahl mit einfacher Genauigkeit ist oder mit dieser übereinstimmt.

Equals(Object)

Gibt einen Wert zurück, der angibt, ob diese Instanz gleich einem angegebenen Objekt ist.

Equals(Single)

Gibt einen Wert zurück, der angibt, ob diese Instanz und ein angegebenes Single-Objekt den gleichen Wert darstellen.

GetHashCode()

Gibt den Hashcode für diese Instanz zurück.

GetTypeCode()

Gibt den TypeCode für den Werttyp Single zurück.

IsFinite(Single)

Bestimmt, ob der angegebene Wert endlich ist (Null, subnormal oder normal).

IsInfinity(Single)

Gibt einen Wert zurück, der angibt, ob der Wert der angegebenen Zahl -unendlich oder +unendlich ist.

IsNaN(Single)

Gibt einen Wert zurück, der angibt, ob der angegebene Wert keine Zahl ist (NaN).

IsNegative(Single)

Bestimmt, ob der angegebene Wert negativ ist.

IsNegativeInfinity(Single)

Gibt einen Wert zurück, der angibt, ob die angegebene Zahl minus unendlich ergibt.

IsNormal(Single)

Bestimmt, ob der angegebene Wert normal ist.

IsPositiveInfinity(Single)

Gibt einen Wert zurück, der angibt, ob die angegebene Zahl plus unendlich ergibt.

IsSubnormal(Single)

Bestimmt, ob der angegebene Wert subnormal ist.

Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider)

Konvertiert eine Zeichenspanne mit der Zeichenfolgendarstellung einer Zahl in einem angegebenen Stil und einem kulturspezifischen Format in die entsprechende Gleitkommazahl mit einfacher Genauigkeit

Parse(String)

Konvertiert die Zeichenfolgendarstellung einer Zahl in die entsprechende Gleitkommazahl mit einfacher Genauigkeit.

Parse(String, IFormatProvider)

Konvertiert die Zeichenfolgendarstellung einer Zahl in einem bestimmten kulturabhängigen Format in die entsprechende Gleitkommazahl mit einfacher Genauigkeit.

Parse(String, NumberStyles)

Konvertiert die Zeichenfolgendarstellung einer Zahl in einem angegebenen Stil in die entsprechende Gleitkommazahl mit einfacher Genauigkeit.

Parse(String, NumberStyles, IFormatProvider)

Konvertiert die Zeichenfolgendarstellung einer Zahl in einem angegebenen Stil und einem kulturabhängigen Format in die entsprechende Gleitkommazahl mit einfacher Genauigkeit.

ToString()

Konvertiert den Wert dieser Instanz in die entsprechende Zeichenfolgendarstellung.

ToString(IFormatProvider)

Konvertiert den numerischen Wert dieser Instanz unter Berücksichtigung der angegebenen kulturabhängigen Formatierungsinformationen in die entsprechende Zeichenfolgendarstellung.

ToString(String)

Konvertiert den numerischen Wert dieser Instanz in die entsprechende Zeichenfolgendarstellung unter Berücksichtigung des angegebenen Formats.

ToString(String, IFormatProvider)

Konvertiert den numerischen Wert dieser Instanz unter Verwendung des angegebenen Formats und der angegebenen kulturabhängigen Formatierungsinformationen in die entsprechende Zeichenfolgendarstellung.

TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)

Versucht, den Wert der aktuellen Instanz der Gleitkommazahl in die angegebene Zeichenspanne zu formatieren

TryParse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider, Single)

Konvertiert die Spannendarstellung einer Zahl in einem angegebenen Stil und einem kulturabhängigen Format in die entsprechende Gleitkommazahl mit einfacher Genauigkeit Ein Rückgabewert gibt an, ob die Konvertierung erfolgreich war oder nicht.

TryParse(ReadOnlySpan<Char>, Single)

Konvertiert die Zeichenfolgendarstellung einer Zahl in einer Zeichenspanne in die entsprechende Gleitkommazahl mit einfacher Genauigkeit. Ein Rückgabewert gibt an, ob die Konvertierung erfolgreich war oder nicht.

TryParse(String, NumberStyles, IFormatProvider, Single)

Konvertiert die Zeichenfolgendarstellung einer Zahl in einem angegebenen Stil und einem kulturabhängigen Format in die entsprechende Gleitkommazahl mit einfacher Genauigkeit. Ein Rückgabewert gibt an, ob die Konvertierung erfolgreich war oder nicht.

TryParse(String, Single)

Konvertiert die Zeichenfolgendarstellung einer Zahl in die entsprechende Gleitkommazahl mit einfacher Genauigkeit. Ein Rückgabewert gibt an, ob die Konvertierung erfolgreich war oder nicht.

Operatoren

Equality(Single, Single)

Gibt einen Wert zurück, der angibt, ob zwei angegebene Single-Werte gleich sind.

GreaterThan(Single, Single)

Gibt einen Wert zurück, der angibt, ob ein angegebener Single-Wert größer als ein anderer angegebener Single-Wert ist.

GreaterThanOrEqual(Single, Single)

Gibt einen Wert zurück, der angibt, ob ein angegebener Single-Wert größer oder gleich einem anderen angegebenen Single-Wert ist.

Inequality(Single, Single)

Gibt einen Wert zurück, der angibt, ob zwei angegebene Single-Werte gleich sind.

LessThan(Single, Single)

Gibt einen Wert zurück, der angibt, ob ein angegebener Single-Wert größer als ein anderer angegebener Single-Wert ist.

LessThanOrEqual(Single, Single)

Gibt einen Wert zurück, der angibt, ob ein angegebener Single -Wert kleiner oder gleich einem anderen angegebenen Single-Wert ist.

Explizite Schnittstellenimplementierungen

IComparable.CompareTo(Object)

Vergleicht die aktuelle Instanz mit einem anderen Objekt vom selben Typ und gibt eine ganze Zahl zurück, die angibt, ob die aktuelle Instanz in der Sortierreihenfolge vor oder nach dem anderen Objekt oder an derselben Position auftritt.

IConvertible.GetTypeCode()

Gibt den TypeCode für diese Instanz zurück.

IConvertible.ToBoolean(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToBoolean(IFormatProvider).

IConvertible.ToByte(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToByte(IFormatProvider).

IConvertible.ToChar(IFormatProvider)

Diese Konvertierung wird nicht unterstützt. Bei dem Versuch der Verwendung dieser Methode wird eine InvalidCastException ausgelöst.

IConvertible.ToDateTime(IFormatProvider)

Diese Konvertierung wird nicht unterstützt. Bei dem Versuch der Verwendung dieser Methode wird eine InvalidCastException ausgelöst.

IConvertible.ToDecimal(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToDecimal(IFormatProvider).

IConvertible.ToDouble(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToDouble(IFormatProvider).

IConvertible.ToInt16(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToInt16(IFormatProvider).

IConvertible.ToInt32(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToInt32(IFormatProvider).

IConvertible.ToInt64(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToInt64(IFormatProvider).

IConvertible.ToSByte(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToSByte(IFormatProvider).

IConvertible.ToSingle(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToSingle(IFormatProvider).

IConvertible.ToType(Type, IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToType(Type, IFormatProvider).

IConvertible.ToUInt16(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToUInt16(IFormatProvider).

IConvertible.ToUInt32(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToUInt32(IFormatProvider).

IConvertible.ToUInt64(IFormatProvider)

Eine Beschreibung dieses Elements finden Sie unter ToUInt64(IFormatProvider).

Gilt für

Threadsicherheit

Alle Member dieses Typs sind threadsicher. Member, die den Instanzzustand zu ändern scheinen, geben tatsächlich eine neue Instanz zurück, die mit dem neuen Wert initialisiert wurde. Wie bei jedem anderen Typ muss das Lesen und Schreiben in eine freigegebene Variable, die eine Instanz dieses Typs enthält, durch eine Sperre geschützt werden, um threadsicherheit zu gewährleisten.

Siehe auch