Single Structure

Définition

Représente un nombre à virgule flottante simple précision.

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
Héritage
Single
Attributs
Implémente

Remarques

Le Single type de valeur représente un nombre 32 à simple précision dont les valeurs sont comprises entre 3.402823 E38 négatif et 3.402823 E38 positif, ainsi qu’un zéro positif ou négatif, PositiveInfinity , NegativeInfinity et non un nombre ( NaN ). Elle est destinée à représenter des valeurs extrêmement volumineuses (telles que les distances entre les planètes ou les galaxies) ou très petites (par exemple, la masse moléculaire d’une substance en kilogrammes) et qui sont souvent imprécises (par exemple, la distance entre la terre et un autre système solaire). Le Single type est conforme à la norme IEC 60559:1989 (IEEE 754) pour l’arithmétique à virgule flottante binaire.

Cet article comprend les sections suivantes :

System.Single fournit des méthodes pour comparer des instances de ce type, pour convertir la valeur d’une instance en sa représentation sous forme de chaîne et pour convertir la représentation sous forme de chaîne d’un nombre en une instance de ce type. Pour plus d’informations sur la façon dont les codes de spécification de format contrôlent la représentation sous forme de chaîne des types valeur, consultez mise en forme des types, chaînes de format numériques standardet chaînes de format numériques personnalisées.

Représentation à virgule flottante et précision

Le Single type de données stocke des valeurs à virgule flottante simple précision dans un format binaire 32 bits, comme indiqué dans le tableau suivant :

Élément Bits
Mantisse ou mantisse 0-22
Exponent 23-30
Sign (0 = positif, 1 = négatif) 31

Tout comme les fractions décimales ne peuvent pas représenter précisément des valeurs fractionnaires (par exemple Math.PI , 1/3 ou), les fractions binaires ne peuvent pas représenter des valeurs fractionnaires. Par exemple, 2/10, qui est représenté précisément par 0,2 comme une fraction décimale, est représenté par. 0011111001001100 comme une fraction binaire, avec le modèle « 1100 » qui se répète à l’infini. Dans ce cas, la valeur à virgule flottante fournit une représentation imprécise du nombre qu’elle représente. L’exécution d’opérations mathématiques supplémentaires sur la valeur à virgule flottante d’origine augmente souvent son manque de précision. Par exemple, si vous comparez les résultats de la multiplication de. 3 par 10 et que vous ajoutez. 3 à. 3 9 fois, vous verrez que l’addition produit le résultat le moins précis, car il implique huit opérations supplémentaires que la multiplication. Notez que cette disparité est apparente uniquement si vous affichez les deux Single valeurs à l’aide de la chaîne de format numérique standard« R », qui, si nécessaire, affiche les 9 chiffres de précision pris en charge par le Single type.

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

Comme certains nombres ne peuvent pas être représentés exactement comme des valeurs binaires fractionnaires, les nombres à virgule flottante peuvent uniquement se rapprocher des nombres réels.

Tous les nombres à virgule flottante ont un nombre limité de chiffres significatifs, qui détermine également la précision avec laquelle une valeur à virgule flottante se rapproche d’un nombre réel. Une Single valeur a jusqu’à 7 chiffres décimaux de précision, bien qu’un maximum de 9 chiffres soit géré en interne. Cela signifie que certaines opérations à virgule flottante peuvent ne pas avoir la précision pour modifier une valeur à virgule flottante. L’exemple suivant définit une valeur à virgule flottante simple précision volumineuse, puis ajoute le produit de Single.Epsilon et un quadrillion à celui-ci. Toutefois, le produit est trop petit pour modifier la valeur à virgule flottante d’origine. Son chiffre le moins significatif est les millièmes, tandis que le chiffre le plus significatif dans le produit est de 10à 30.

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

La précision limitée d’un nombre à virgule flottante a plusieurs conséquences :

  • Deux nombres à virgule flottante qui apparaissent égaux pour une précision particulière peuvent ne pas l'être parce que leurs chiffres de droite sont différents. Dans l’exemple suivant, une série de nombres est ajoutée ensemble, et son total est comparé au total prévu. Bien que les deux valeurs semblent identiques, un appel à la Equals méthode indique qu’elles ne le sont pas.

    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).
    

    Si vous modifiez les éléments de mise en forme dans l' Console.WriteLine(String, Object, Object) instruction de {0} et {1} en {0:R} et pour {1:R} Afficher tous les chiffres significatifs des deux Single valeurs, il est clair que les deux valeurs sont inégales en raison d’une perte de précision pendant les opérations d’addition. Dans ce cas, le problème peut être résolu en appelant la Math.Round(Double, Int32) méthode pour arrondir les Single valeurs à la précision souhaitée avant d’effectuer la comparaison.

  • Une opération mathématique ou de comparaison qui utilise un nombre à virgule flottante peut ne pas donner le même résultat si un nombre décimal est utilisé, car le nombre à virgule flottante binaire peut ne pas être égal au nombre décimal. Un exemple précédent illustre cela en affichant le résultat de la multiplication de. 3 par 10 et en ajoutant. 3 à. 3 9 fois.

    Lorsque la précision dans les opérations numériques avec des valeurs fractionnaires est importante, utilisez le type à la Decimal place du Single type. Lorsque la précision dans les opérations numériques avec des valeurs intégrales au-delà de la plage des Int64 UInt64 types ou est importante, utilisez le BigInteger type.

  • Une valeur peut ne pas aller-retour si un nombre à virgule flottante est impliqué. Une valeur est dite aller-retour si une opération convertit un nombre à virgule flottante d’origine en une autre forme, une opération inverse transforme le formulaire converti en nombre à virgule flottante, et le nombre à virgule flottante final est égal au nombre à virgule flottante d’origine. L’aller-retour peut échouer parce qu’un ou plusieurs chiffres les moins significatifs sont perdus ou modifiés dans une conversion. Dans l’exemple suivant, trois Single valeurs sont converties en chaînes et enregistrées dans un fichier. Comme le montre la sortie, bien que les valeurs semblent identiques, les valeurs restaurées ne sont pas égales aux valeurs d’origine.

    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
    

    Dans ce cas, les valeurs peuvent être arrondies avec succès à l’aide de la chaîne de format numérique standard « G9 » afin de conserver la précision totale des Single valeurs, comme le montre l’exemple suivant.

    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 les valeurs ont une précision inférieure à celle des Double valeurs. Une Single valeur qui est convertie en apparemment équivalente Double n’est souvent pas égale à la Double valeur en raison de différences de précision. Dans l’exemple suivant, le résultat des opérations de division identiques est affecté à une Double valeur et à une Single valeur. Une fois que la Single valeur est castée en Double , une comparaison des deux valeurs indique qu’elles sont inégales.

    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
    

    Pour éviter ce problème, utilisez le Double type de données à la place du Single type de données ou utilisez la Round méthode afin que les deux valeurs aient la même précision.

Test de l’égalité

Pour être considéré comme égal, deux Single valeurs doivent représenter des valeurs identiques. Toutefois, en raison de différences de précision entre les valeurs, ou en raison d’une perte de précision par une ou les deux valeurs, les valeurs à virgule flottante supposées être identiques sont souvent inégales en raison de différences dans leurs chiffres les moins significatifs. Par conséquent, les appels à la Equals méthode pour déterminer si deux valeurs sont égales, ou les appels à la CompareTo méthode pour déterminer la relation entre deux Single valeurs, produisent souvent des résultats inattendus. Cela est évident dans l’exemple suivant, où deux valeurs apparemment égales ne Single sont pas égales, car la première valeur a 7 chiffres de précision, tandis que la deuxième valeur est 9.

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

Les valeurs calculées qui suivent des chemins de code différents et qui sont manipulés de différentes façons s’avèrent souvent inégales. Dans l’exemple suivant, une Single valeur est carrée, puis la racine carrée est calculée pour restaurer la valeur d’origine. Une seconde Single est multipliée par 3,51 et au carré avant que la racine carrée du résultat soit divisée par 3,51 pour restaurer la valeur d’origine. Bien que les deux valeurs semblent identiques, un appel à la Equals(Single) méthode indique qu’elles ne sont pas égales. L’utilisation de la chaîne de format standard « G9 » pour retourner une chaîne de résultat qui affiche tous les chiffres significatifs de chaque Single valeur indique que la deuxième valeur est .0000000000001 inférieure à la première.

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

Dans les cas où une perte de précision est susceptible d’affecter le résultat d’une comparaison, vous pouvez utiliser les techniques suivantes au lieu d’appeler la Equals CompareTo méthode ou :

  • Appelez la Math.Round méthode pour vous assurer que les deux valeurs ont la même précision. L’exemple suivant modifie un exemple précédent pour utiliser cette approche afin que deux valeurs fractionnaires soient équivalentes.

    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
    

    Le problème de précision s’applique toujours à l’arrondi des valeurs de milieu. Pour plus d'informations, voir la méthode Math.Round(Double, Int32, MidpointRounding).

  • Test de l’égalité approximative au lieu de l’égalité. Cette technique nécessite que vous définissiez une valeur absolue selon laquelle les deux valeurs peuvent différer, mais toujours égales, ou que vous définissiez une valeur relative par laquelle la valeur la plus petite peut s’écarter de la plus grande valeur.

    Avertissement

    Single.Epsilon est parfois utilisé comme mesure absolue de la distance entre deux Single valeurs lors du test d’égalité. Toutefois, Single.Epsilon mesure la plus petite valeur possible qui peut être ajoutée ou soustraite d’un Single dont la valeur est égale à zéro. Pour la plupart des valeurs positives et négatives Single , la valeur de Single.Epsilon est trop petite pour être détectée. Par conséquent, à l’exception des valeurs qui sont égales à zéro, nous ne recommandons pas son utilisation dans les tests d’égalité.

    L’exemple suivant utilise la dernière approche pour définir une IsApproximatelyEqual méthode qui teste la différence relative entre deux valeurs. Il compare également le résultat des appels à la IsApproximatelyEqual méthode et à la Equals(Single) méthode.

    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
    

Valeurs à virgule flottante et exceptions

Les opérations avec des valeurs à virgule flottante ne lèvent pas d’exceptions, contrairement aux opérations avec des types intégraux, qui lèvent des exceptions dans les cas d’opérations illégales telles que la division par zéro ou le dépassement de capacité. Au lieu de cela, dans ce cas, le résultat d’une opération à virgule flottante est zéro, l’infini positif, l’infini négatif ou une valeur non numérique (NaN) :

  • Si le résultat d’une opération à virgule flottante est trop petit pour le format de destination, le résultat est égal à zéro. Cela peut se produire lorsque deux nombres à virgule flottante très petits sont multipliés, comme le montre l’exemple suivant.

    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
    
  • Si la grandeur du résultat d’une opération à virgule flottante dépasse la plage du format de destination, le résultat de l’opération est PositiveInfinity ou NegativeInfinity , selon le cas pour le signe du résultat. Le résultat d’une opération qui dépasse le résultat Single.MaxValue est PositiveInfinity , et le résultat d’une opération qui dépasse le résultat Single.MinValue est NegativeInfinity , comme le montre l’exemple suivant.

    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 résulte également d’une division par zéro avec un dividende positif et des NegativeInfinity résultats d’une division par zéro avec un dividende négatif.

  • Si une opération à virgule flottante n’est pas valide, le résultat de l’opération est NaN . Par exemple, NaN les résultats des opérations suivantes :

    • Division par zéro avec un dividende égal à zéro. Notez que les autres cas de division par zéro entraînent PositiveInfinity ou NegativeInfinity .

    • Toute opération à virgule flottante avec une entrée non valide. Par exemple, la tentative de recherche de la racine carrée d’une valeur négative retourne NaN .

    • Toute opération avec un argument dont la valeur est Single.NaN .

Conversions de type et structure unique

La Single structure ne définit pas d’opérateurs de conversion explicites ou implicites ; à la place, les conversions sont implémentées par le compilateur.

Le tableau suivant répertorie les conversions possibles d’une valeur d’autres types numériques primitifs en une Single valeur, mais indique également si la conversion est étendue ou restrictive et si le résultant Single peut avoir une précision inférieure à la valeur d’origine.

Conversion de Élargissement/réduction Perte possible de précision
Byte Widening Non
Decimal Widening

Notez que C# requiert un opérateur de conversion.
Oui. Decimal prend en charge 29 chiffres décimaux de précision ; Single prend en charge 9.
Double Restrictive les valeurs hors limites sont converties en Double.NegativeInfinity ou Double.PositiveInfinity . Oui. Double prend en charge 17 chiffres décimaux de précision ; Single prend en charge 9.
Int16 Widening Non
Int32 Widening Oui. Int32 prend en charge 10 chiffres décimaux de précision ; Single prend en charge 9.
Int64 Widening Oui. Int64 prend en charge 19 chiffres décimaux de précision ; Single prend en charge 9.
SByte Widening Non
UInt16 Widening Non
UInt32 Widening Oui. UInt32 prend en charge 10 chiffres décimaux de précision ; Single prend en charge 9.
UInt64 Widening Oui. Int64 prend en charge 20 chiffres décimaux de précision ; Single prend en charge 9.

L’exemple suivant convertit la valeur minimale ou maximale d’autres types numériques primitifs en une Single valeur.

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)

En outre, les Double valeurs Double.NaN , Double.PositiveInfinity et sont Double.NegativeInfinity respectivement converties en Single.NaN , Single.PositiveInfinity et Single.NegativeInfinity .

Notez que la conversion de la valeur de certains types numériques en Single valeur peut impliquer une perte de précision. Comme l’illustre l’exemple, une perte de précision est possible lors de la conversion des valeurs,,,, Decimal Double Int32 Int64 UInt32 et UInt64 en Single valeurs.

La conversion d’une Single valeur en Double est une conversion étendue. La conversion peut entraîner une perte de précision si le Double type n’a pas de représentation précise pour la Single valeur.

La conversion d’une Single valeur en une valeur de n’importe quel type de données numérique primitif autre qu’un Double est une conversion restrictive et requiert un opérateur de cast (en C#) ou une méthode de conversion (en Visual Basic). Les valeurs qui se trouvent en dehors de la plage du type de données cible, qui sont définies par les propriétés et du type cible MinValue MaxValue , se comportent comme indiqué dans le tableau suivant.

Type cible Résultat
Tout type intégral OverflowExceptionException si la conversion se produit dans un contexte vérifié.

Si la conversion se produit dans un contexte non vérifié (valeur par défaut en C#), l’opération de conversion s’effectue correctement, mais la valeur déborde.
Decimal Une OverflowException exception,

En outre, Single.NaN , Single.PositiveInfinity et Single.NegativeInfinity lèvent un OverflowException pour les conversions en entiers dans un contexte vérifié, mais ces valeurs sont dépassées en cas de conversion en entiers dans un contexte non vérifié. Pour les conversions en Decimal , elles lèvent toujours un OverflowException . Pour les conversions en Double , elles sont respectivement converties en Double.NaN , Double.PositiveInfinity et Double.NegativeInfinity .

Notez qu’une perte de précision peut résulter de la conversion d’une Single valeur en un autre type numérique. dans le cas de la conversion de valeurs non intégrales Single , comme le montre la sortie de l’exemple, le composant fractionnaire est perdu lorsque la Single valeur est arrondie (comme dans Visual Basic) ou tronquée (comme en C#). Pour les conversions en Decimal valeurs, la Single valeur peut ne pas avoir une représentation précise dans le type de données cible.

L’exemple suivant convertit un certain nombre de Single valeurs en plusieurs autres types numériques. les conversions se produisent dans un contexte vérifié dans Visual Basic (valeur par défaut) et en C# (en raison du mot clé checked ). La sortie de l’exemple montre le résultat des conversions dans un contexte désactivé. vous pouvez effectuer des conversions dans un contexte non vérifié dans Visual Basic en compilant avec le /removeintchecks+ commutateur de compilateur et en C# en commentant l' checked instruction.

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)

pour plus d’informations sur la conversion des types numériques, consultez conversion de type dans le .NET Framework et Tables de conversion de type.

Fonctionnalités à virgule flottante

La Single structure et les types connexes fournissent des méthodes pour effectuer les catégories d’opérations suivantes :

  • Comparaison des valeurs. Vous pouvez appeler la Equals méthode pour déterminer si deux Single valeurs sont égales ou la CompareTo méthode pour déterminer la relation entre deux valeurs.

    La Single structure prend également en charge un jeu complet d’opérateurs de comparaison. Par exemple, vous pouvez tester l’égalité ou l’inégalité, ou déterminer si une valeur est supérieure ou égale à une autre valeur. Si l’un des opérandes est un Double , la Single valeur est convertie en Double avant d’effectuer la comparaison. Si l’un des opérandes est un type intégral, il est converti en un Single avant d’effectuer la comparaison. Bien qu’il s’agisse de conversions étendues, elles peuvent impliquer une perte de précision.

    Avertissement

    En raison des différences de précision, deux Single valeurs qui sont égales peuvent ne pas être égales, ce qui affecte le résultat de la comparaison. Pour plus d’informations sur la comparaison de deux valeurs, consultez la section test d’égalité Single .

    Vous pouvez également appeler les IsNaN méthodes,, IsInfinity IsPositiveInfinity et IsNegativeInfinity pour tester ces valeurs spéciales.

  • Opérations mathématiques. Les opérations arithmétiques courantes telles que l’addition, la soustraction, la multiplication et la division sont implémentées par les compilateurs de langages et les instructions Common Intermediate Language (CIL) plutôt que par les Single méthodes. Si l’autre opérande dans une opération mathématique est un Double , le Single est converti en un Double avant d’effectuer l’opération, et le résultat de l’opération est également une Double valeur. Si l’autre opérande est un type intégral, il est converti en un Single avant d’effectuer l’opération, et le résultat de l’opération est également une Single valeur.

    vous pouvez effectuer d’autres opérations mathématiques en static appelant Shared les méthodes (dans Visual Basic) de la System.Math classe. Celles-ci incluent des méthodes supplémentaires couramment utilisées pour les opérations arithmétiques (telles que Math.Abs , Math.Sign et Math.Sqrt ), la géométrie (comme Math.Cos et Math.Sin ) et le calcul (par exemple, Math.Log ). Dans tous les cas, la Single valeur est convertie en Double .

    Vous pouvez également manipuler les bits individuels dans une Single valeur. La BitConverter.GetBytes(Single) méthode retourne son modèle binaire dans un tableau d’octets. En passant ce tableau d’octets à la BitConverter.ToInt32 méthode, vous pouvez également conserver le Single modèle binaire de la valeur dans un entier 32 bits.

  • Arrondi. L’arrondi est souvent utilisé comme une technique pour réduire l’impact des différences entre les valeurs provoquées par les problèmes de représentation à virgule flottante et de précision. Vous pouvez arrondir une Single valeur en appelant la Math.Round méthode. Toutefois, Notez que la Single valeur est convertie en Double avant que la méthode ne soit appelée, et la conversion peut impliquer une perte de précision.

  • Mise en forme. Vous pouvez convertir une Single valeur en représentation sous forme de chaîne en appelant la ToString méthode ou en utilisant la fonctionnalité de mise en forme composite . Pour plus d’informations sur la façon dont les chaînes de format contrôlent la représentation sous forme de chaîne des valeurs à virgule flottante, consultez les rubriques chaînes de format numériques standard et chaînes de format numériques personnalisées .

  • Analyse des chaînes. Vous pouvez convertir la représentation sous forme de chaîne d’une valeur à virgule flottante en Single valeur en appelant la Parse TryParse méthode ou. Si l’opération d’analyse échoue, la Parse méthode lève une exception, tandis que la TryParse méthode retourne false .

  • Conversion de type. la Single structure fournit une implémentation d’interface explicite pour l' IConvertible interface, qui prend en charge la conversion entre deux types de données .NET Framework standard. Les compilateurs de langage prennent également en charge la conversion implicite de valeurs pour tous les autres types numériques standard, à l’exception de la conversion de Double en Single valeurs. La conversion d’une valeur de n’importe quel type numérique standard autre qu’un Double en a Single est une conversion étendue et ne nécessite pas l’utilisation d’un opérateur de cast ou d’une méthode de conversion.

    Toutefois, la conversion de valeurs entières 32 bits et 64 bits peut impliquer une perte de précision. Le tableau suivant répertorie les différences de précision pour les types 32 bits, 64-bits et Double :

    Type Précision maximale (en chiffres décimaux) Précision interne (en chiffres décimaux)
    Double 15 17
    Int32 et UInt32 10 10
    Int64 et UInt64 19 19
    Single 7 9

    Le problème de la précision le plus souvent affecte les Single valeurs qui sont converties en Double valeurs. Dans l’exemple suivant, deux valeurs produites par des opérations de division identiques sont inégales, car l’une des valeurs est une valeur à virgule flottante simple précision qui est convertie en Double .

    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
    

Champs

Epsilon

Représente la valeur Single positive la plus petite qui est supérieure à zéro. Ce champ est constant.

MaxValue

Représente la plus grande valeur possible de Single. Ce champ est constant.

MinValue

Représente la plus petite valeur possible de Single. Ce champ est constant.

NaN

Représente une valeur autre qu'un nombre (NaN). Ce champ est constant.

NegativeInfinity

Représente l'infini négatif. Ce champ est constant.

PositiveInfinity

Représente l'infini positif. Ce champ est constant.

Méthodes

CompareTo(Object)

Compare cette instance à un objet spécifié et retourne un entier qui indique si la valeur de cette instance est inférieure, égale ou supérieure à la valeur de l'objet spécifié.

CompareTo(Single)

Compare cette instance à un nombre à virgule flottante simple précision spécifié et retourne un entier qui indique si la valeur de cette instance est inférieure, égale ou supérieure à celle du nombre à virgule flottante simple précision spécifié.

Equals(Object)

Retourne une valeur indiquant si cette instance équivaut à un objet spécifié.

Equals(Single)

Retourne une valeur indiquant si cette instance et un objet Single spécifié représentent la même valeur.

GetHashCode()

Retourne le code de hachage de cette instance.

GetTypeCode()

Retourne le TypeCode du type valeur Single.

IsFinite(Single)

Détermine si la valeur spécifiée est finie (zéro, inférieure à la normale ou normale).

IsInfinity(Single)

Retourne une valeur indiquant si la valeur du nombre spécifié est l'infini négatif ou positif.

IsNaN(Single)

Retourne une valeur qui indique si la valeur spécifiée n'est pas un nombre (NaN).

IsNegative(Single)

Détermine si la valeur spécifiée est négative.

IsNegativeInfinity(Single)

Retourne une valeur indiquant si le nombre spécifié est équivalent à l'infini négatif.

IsNormal(Single)

Détermine si la valeur spécifiée est normale.

IsPositiveInfinity(Single)

Retourne une valeur indiquant si le nombre spécifié est équivalent à l'infini positif.

IsSubnormal(Single)

Détermine si la valeur spécifiée est inférieure à la normale.

Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider)

Convertit une étendue de caractères contenant la représentation sous forme de chaîne d’un nombre dans un style et un format propres à la culture spécifiés en nombre à virgule flottante simple précision équivalent.

Parse(String)

Convertit la chaîne d'un nombre en nombre à virgule flottante simple précision équivalent.

Parse(String, IFormatProvider)

Convertit la chaîne d'un nombre dans un format propre à la culture spécifiée en nombre à virgule flottante simple précision équivalent.

Parse(String, NumberStyles)

Convertit la chaîne d'un nombre dans un style spécifié en nombre à virgule flottante simple précision équivalent.

Parse(String, NumberStyles, IFormatProvider)

Convertit la chaîne d'un nombre dans un style et un format propre à la culture spécifiés en nombre à virgule flottante simple précision équivalent.

ToString()

Convertit la valeur numérique de cette instance en sa représentation équivalente sous forme de chaîne.

ToString(IFormatProvider)

Convertit la valeur numérique de cette instance en sa représentation sous forme de chaîne équivalente à l'aide des informations de format spécifiques à la culture donnée.

ToString(String)

Convertit la valeur numérique de cette instance en sa représentation sous forme de chaîne équivalente en utilisant le format spécifié.

ToString(String, IFormatProvider)

Convertit la valeur numérique de cette instance en sa représentation sous forme de chaîne équivalente à l'aide du format spécifié et des informations de format spécifiques à la culture.

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

Tente de mettre en forme la valeur de l’instance de nombre à virgule flottante actuelle dans la plage de caractères fournie.

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

Convertit la chaîne d'un nombre dans un style et un format propres à la culture spécifiés en nombre à virgule flottante simple précision équivalent. Une valeur de retour indique si la conversion a réussi ou a échoué.

TryParse(ReadOnlySpan<Char>, Single)

Convertit la chaîne d'un nombre dans une étendue de caractères en nombre à virgule flottante simple précision équivalent. Une valeur de retour indique si la conversion a réussi ou a échoué.

TryParse(String, NumberStyles, IFormatProvider, Single)

Convertit la chaîne d'un nombre dans un style et un format propres à la culture spécifiés en nombre à virgule flottante simple précision équivalent. Une valeur de retour indique si la conversion a réussi ou a échoué.

TryParse(String, Single)

Convertit la chaîne d'un nombre en nombre à virgule flottante simple précision équivalent. Une valeur de retour indique si la conversion a réussi ou a échoué.

Opérateurs

Equality(Single, Single)

Retourne une valeur qui indique si deux valeurs Single spécifiées sont égales.

GreaterThan(Single, Single)

Retourne une valeur qui indique si une valeur Single spécifique est supérieure à une autre valeur Single spécifique.

GreaterThanOrEqual(Single, Single)

Retourne une valeur qui indique si une valeur Single spécifique est supérieure ou égale à une autre valeur Single spécifique.

Inequality(Single, Single)

Retourne une valeur qui indique si deux valeurs Single spécifiées sont différentes.

LessThan(Single, Single)

Retourne une valeur qui indique si une valeur Single spécifique est inférieure à une autre valeur Single spécifique.

LessThanOrEqual(Single, Single)

Retourne une valeur qui indique si une valeur Single spécifique est inférieure ou égale à une autre valeur Single spécifique.

Implémentations d’interfaces explicites

IComparable.CompareTo(Object)

Compare l'instance actuelle à un autre objet du même type et retourne un entier qui indique si l'instance actuelle précède ou suit un autre objet ou se trouve à la même position que ce dernier dans l'ordre de tri.

IConvertible.GetTypeCode()

Retourne le TypeCode de cette instance.

IConvertible.ToBoolean(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToBoolean(IFormatProvider).

IConvertible.ToByte(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToByte(IFormatProvider).

IConvertible.ToChar(IFormatProvider)

Cette conversion n'est pas prise en charge. Toute tentative d'utilisation de cette méthode lève une InvalidCastException.

IConvertible.ToDateTime(IFormatProvider)

Cette conversion n'est pas prise en charge. Toute tentative d'utilisation de cette méthode lève une InvalidCastException.

IConvertible.ToDecimal(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToDecimal(IFormatProvider).

IConvertible.ToDouble(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToDouble(IFormatProvider).

IConvertible.ToInt16(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToInt16(IFormatProvider).

IConvertible.ToInt32(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToInt32(IFormatProvider).

IConvertible.ToInt64(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToInt64(IFormatProvider).

IConvertible.ToSByte(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToSByte(IFormatProvider).

IConvertible.ToSingle(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToSingle(IFormatProvider).

IConvertible.ToType(Type, IFormatProvider)

Pour obtenir une description de ce membre, consultez ToType(Type, IFormatProvider).

IConvertible.ToUInt16(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToUInt16(IFormatProvider).

IConvertible.ToUInt32(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToUInt32(IFormatProvider).

IConvertible.ToUInt64(IFormatProvider)

Pour obtenir une description de ce membre, consultez ToUInt64(IFormatProvider).

S’applique à

Cohérence de thread

Tous les membres de ce type sont thread-safe. Les membres qui semblent modifier l’état de l’instance retournent en fait une nouvelle instance initialisée avec la nouvelle valeur. Comme pour tout autre type, la lecture et l’écriture dans une variable partagée qui contient une instance de ce type doivent être protégées par un verrou pour garantir la sécurité des threads.

Voir aussi