Questa pagina è stata utile?
I suggerimenti relativi al contenuto di questa pagina sono importanti. Comunicaceli.
Altri suggerimenti?
1500 caratteri rimanenti
Struttura Double
Collapse the table of content
Expand the table of content
Il presente articolo è stato tradotto automaticamente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale. Ulteriori informazioni.
Traduzione
Originale

Struttura Double

Rappresenta un numero in virgola mobile a precisione doppia.

Spazio dei nomi:  System
Assembly:  mscorlib (in mscorlib.dll)

[SerializableAttribute]
[ComVisibleAttribute(true)]
public struct Double : IComparable, IFormattable, 
	IConvertible, IComparable<double>, IEquatable<double>

Il tipo Double espone i seguenti membri.

  NomeDescrizione
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreCompareTo(Double) Confronta questa istanza con un numero in virgola mobile a precisione doppia specificato e restituisce un valore intero che indica se il valore di questa istanza è minore, uguale o maggiore del valore del numero in virgola mobile a precisione doppia specificato.
Metodo pubblicoSupportato da XNA FrameworkCompareTo(Object)Confronta questa istanza con un oggetto specificato e restituisce un valore intero che indica se il valore di questa istanza è minore, uguale o maggiore rispetto al valore dell'oggetto specificato.
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreEquals(Double)Restituisce un valore che indica se l'istanza e un oggetto Double specificato rappresentano lo stesso valore.
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreEquals(Object) Restituisce un valore che indica se questa istanza è uguale ad un oggetto specificato. (Esegue l'override di ValueType.Equals(Object)).
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreGetHashCode Restituisce il codice hash per questa istanza. (Esegue l'override di ValueType.GetHashCode()).
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreGetType Ottiene il Type dell'istanza corrente. (Ereditato da Object)
Metodo pubblicoSupportato da XNA FrameworkGetTypeCode Restituisce l'oggetto TypeCode per il tipo valore Double.
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreIsInfinity Restituisce un valore che indica se il numero specificato è valutato come infinito negativo o positivo
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreIsNaNRestituisce un valore che indica se il valore specificato non è un numero (NaN).
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreIsNegativeInfinity Restituisce un valore che indica se il numero specificato è valutato come infinito negativo.
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreIsPositiveInfinity Restituisce un valore che indica se il numero specificato è valutato come infinito positivo.
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreParse(String) Converte la rappresentazione in forma di stringa di un numero nel rispettivo numero in virgola mobile a precisione doppia equivalente.
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreParse(String, NumberStyles) Converte la rappresentazione in forma di stringa di un numero in uno stile specificato nel rispettivo numero in virgola mobile a precisione doppia equivalente.
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreParse(String, IFormatProvider) Converte la rappresentazione in forma di stringa di un numero in un determinato formato specifico delle impostazioni di cultura nel numero in virgola mobile a doppia precisione equivalente.
Metodo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreParse(String, NumberStyles, IFormatProvider) Converte la rappresentazione in forma di stringa di un numero in uno stile specificato e in un formato specifico delle impostazioni di cultura nel numero in virgola mobile a precisione doppia equivalente.
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreToString() Converte il valore numerico di questa istanza nella sua equivalente rappresentazione in forma di stringa. (Esegue l'override di ValueType.ToString()).
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreToString(IFormatProvider) Converte il valore numerico di questa istanza nella sua equivalente rappresentazione in forma di stringa utilizzando le informazioni di formato specifiche delle impostazioni di cultura.
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreToString(String) Converte il valore numerico di questa istanza nella sua equivalente rappresentazione in forma di stringa usando il formato specificato.
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreToString(String, IFormatProvider) Converte il valore numerico di questa istanza nella sua equivalente rappresentazione in forma di stringa utilizzando il formato specificato e le informazioni di formattazione specifiche delle impostazioni di cultura.
Metodo pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreTryParse(String, Double) Converte la rappresentazione in forma di stringa di un numero nel rispettivo numero in virgola mobile a precisione doppia equivalente. Un valore restituito indica se la conversione è riuscita o meno.
Metodo pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreTryParse(String, NumberStyles, IFormatProvider, Double) Converte la rappresentazione in forma di stringa di un numero in uno stile specificato e in un formato specifico delle impostazioni di cultura nel numero in virgola mobile a precisione doppia equivalente. Un valore restituito indica se la conversione è riuscita o meno.
In alto

  NomeDescrizione
Operatore pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreEqualityRestituisce un valore che indica se due valori Double specificati sono uguali.
Operatore pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreGreaterThanRestituisce un valore che indica se un valore Double specificato è maggiore di un altro valore Double specificato.
Operatore pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreGreaterThanOrEqualRestituisce un valore che indica se un valore Double specificato è maggiore o uguale a un altro valore Double specificato.
Operatore pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreInequalityRestituisce un valore che indica se due valori Double specificati non sono uguali.
Operatore pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreLessThanRestituisce un valore che indica se il valore Double specificato è minore o uguale a un altro valore Double specificato.
Operatore pubblicoMembro staticoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreLessThanOrEqualRestituisce un valore che indica se un valore Double specificato è minore o uguale a un altro valore Double specificato.
In alto

  NomeDescrizione
Campo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreEpsilonRappresenta il valore Double positivo più piccolo maggiore di zero. Questo campo è costante.
Campo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreMaxValue Rappresenta il valore massimo possibile di un Double. Questo campo è costante.
Campo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreMinValueRappresenta il valore più piccolo possibile di Double. Questo campo è costante.
Campo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreNaN Rappresenta un valore che non è un numero (NaN). Questo campo è costante.
Campo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreNegativeInfinityRappresenta l'infinito negativo. Questo campo è costante.
Campo pubblicoMembro staticoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StorePositiveInfinityRappresenta l'infinito positivo. Questo campo è costante.
In alto

  NomeDescrizione
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreIComparable.CompareTo Confronta l'istanza corrente con un altro oggetto dello stesso tipo e restituisce un numero intero che indica se l'istanza corrente precede, segue, oppure si trova nella stessa posizione nell'ordinamento rispetto all'altro oggetto.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToBooleanInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToBoolean.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToByteInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToByte.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToCharInfrastruttura. Questa conversione non è supportata. Il tentativo di utilizzare questo metodo genera un'eccezione InvalidCastException.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToDateTimeInfrastruttura. Questa conversione non è supportata. Il tentativo di utilizzare questo metodo genera un'eccezione InvalidCastException.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToDecimalInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToDecimal.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToDoubleInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToDouble.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToInt16Infrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToInt16.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToInt32Infrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToInt32.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToInt64Infrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToInt64.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToSByteInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToSByte.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToSingleInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToSingle.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToTypeInfrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToType.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToUInt16Infrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToUInt16.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToUInt32Infrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToUInt32.
Implementazione esplicita dell'interfacciaMetodo privatoSupportato da XNA FrameworkIConvertible.ToUInt64Infrastruttura. Per una descrizione di questo membro, vedere il metodo IConvertible.ToUInt64.
In alto

Il tipo di valore Double rappresenta un numero a 64 bit a doppia precisione con valori compresi tra 1,79769313486232e308 negativo e 1,79769313486232e308 positivo, nonché zero positivo o negativo, PositiveInfinity, NegativeInfinity e valori non numerici (NaN). Viene utilizzato per rappresentare valori di dimensioni estremamente grandi (come distanze tra i pianeti o le galassie) o estremamente ridotte (la massa molecolare di una in sostanza chilogrammi) e che sono spesso imprecisi (ad esempio la distanza fra la terra ed un altro sistema solare), il tipo Double è conforme allo standard IEC 60559:1989 (IEEE 754) per operazioni aritmetiche a virgola mobile binaria.

In questo argomento sono incluse le sezioni seguenti:

Valori a virgola mobile e precisione

Il tipo di dati Double memorizza valori in virgola mobile a doppia precisione in un formato binario a 64 bit, come illustrato nella tabella seguente:

Parte

Bit

Significando o mantissa

0-51

Esponente

52-62

Segno (0 = positivo, 1 = negativo)

63

Come le frazioni decimali non sono in grado di rappresentare con precisione alcuni valori frazionari (come 1/3 o Math.PI), le frazioni binarie non sono in grado di rappresentare alcuni valori frazionari. Ad esempio, 1/10, rappresentato esattamente da 0,1 come frazione decimale, è rappresentato da 0,001100110011 come frazione binaria, con lo schema "0011" che si ripete all'infinito. In questo caso, il valore in virgola mobile fornisce una rappresentazione imprecisa del numero che rappresenta. Eseguire operazioni matematiche aggiuntive sul valore in virgola mobile originale porta spesso ad aumentare la mancanza di precisione. Ad esempio, se confrontiamo il risultato della moltiplicazione di 0,1 per 10 e dell'addizione tra 0,1 e 0,1 per nove volte, vediamo che tale addizione ha prodotto risultati meno accurati dal momento che include otto operazioni ulteriori. Si noti che questa disparità è evidente solo se visualizzano i due valori Double utilizzando la stringa di formato numerico standard "R", che se necessario visualizza tutte le 17 cifre di precisione supportato dal tipo Double.


using System;

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

      Console.WriteLine(".1 * 10:           {0:R}", result1);
      Console.WriteLine(".1 Added 10 times: {0:R}", result2);
   }
}
// The example displays the following output:
//       .1 * 10:           1
//       .1 Added 10 times: 0.99999999999999989


Poiché alcuni numeri non possono essere rappresentato correttamente come valori frazionari binari, i numeri in virgola mobile possono solamente approssimare i numeri reali.

Tutti i numeri in virgola mobile dispongono di un numero di cifre significative limitato, che determina anche il grado di accuratezza con cui un valore in virgola mobile approssima un numero reale. Un valore Double contiene fino a 15 cifre decimali di precisione, anche se internamente vengono mantenute fino a un massimo di 17 cifre. Ciò significa che alcune operazioni in virgola mobile possono mancare di precisione per modificare un valore in virgola mobile. Nell'esempio seguente viene illustrato questo concetto. Definisce un valore in virgola mobile molto grande e quindi aggiunge ad esso il prodotto di Double.Epsilon e di un quadrilione. Il prodotto, comunque, è troppo piccolo per modificare il valore in virgola mobile originale. La meno cifra significativa è rappresentata dalle migliaia, mentre la cifra più significativa nel prodotto è 1^-312.


using System;

public class Example
{
   public static void Main()
   {
      Double value = 123456789012.34567;
      Double additional = Double.Epsilon * 1e12;
      Console.WriteLine("{0} + {1} = {2}", value, additional, 
                                           value + additional);
   }
}
// The example displays the following output:
//    123456789012.346 + 4.94065645841247E-312 = 123456789012.346


La limitata precisione di un numero in virgola mobile comporta diverse conseguenze:

  • Due numeri in virgola mobile apparentemente equivalenti per una particolare precisione potrebbero non risultare uguali a causa di differenze nelle cifre meno significative. Nell'esempio seguente, una serie di numeri vengono sommati assieme ed il totale viene confrontato con il relativo totale previsto. Sebbene i due valori sembrano essere uguali, una chiamata al metodo Equals indica che non lo sono.

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double[] values = { 10.0, 2.88, 2.88, 2.88, 9.0 };
          Double result = 27.64;
          Double total = 0;
          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 (36.64) does not equal the total (36.64).   
    //
    // 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).   
    
    
    

    Se si modificano gli elementi di formato nell'istruzione Console.WriteLine(String, Object, Object) da {0} e {1} a {0:R} e {1:R} per visualizzare tutte le cifre significative dei due valori Double, è chiaro che i due valori sono differenti a causa di una perdita di precisione durante le operazioni di addizione. In questo caso, il problema può essere risolto chiamando il metodo Math.Round(Double, Int32) per arrotondare i valori Double alla precisione desiderata prima di eseguire il confronto.

  • Un'operazione matematica o di confronto in cui si utilizza un numero in virgola mobile potrebbe non restituire lo stesso risultato se viene utilizzato un numero decimale, perché il numero in virgola mobile binario potrebbe non essere equivalente al numero decimale. Un esempio precedente ha illustrato questo mostrando il risultato della moltiplicazione di 0,1 per 10 e dell'addizione di 0,1 per diverse volte.

    Quando la precisione nelle operazioni numeriche con i valori frazionari è importante, è possibile utilizzare Decimal anziché il tipo Double. Quando la precisione nelle operazioni numeriche con i valori interi va oltre l'intervallo dei tipi UInt64 o Int64 è importante utilizzare il tipo BigInteger.

  • Un valore potrebbe non completare la sequenza di andata e ritorno se è coinvolto un numero in virgola mobile. La sequenza di andata e ritorno di un valore viene eseguita se un'operazione converte un numero in virgola mobile originale in un altro formato, un'operazione inversa trasforma il formato convertito nuovamente in un numero in virgola mobile e il numero in virgola mobile finale non è uguale al numero in virgola mobile originale. Questa operazione potrebbe non riuscire perché una o più cifre meno significative vengono perse o modificate in una conversione. Nell'esempio seguente, i tre valori Double vengono convertiti in stringhe e salvati in un file. Come illustrato nell'output, comunque, anche se i valori sembrano essere identici, i valori recuperati non sono uguali a quelli originali.

    
    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Doubles.dat");
          Double[] values = { 2.2/1.01, 1.0/3, Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) {
             sw.Write(values[ctr].ToString());
             if (ctr != values.Length - 1)
                sw.Write("|");
          }      
          sw.Close();
    
          Double[] restoredValues = new Double[values.Length];
          StreamReader sr = new StreamReader(@".\Doubles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Double.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.17821782178218 <> 2.17821782178218
    //       0.333333333333333 <> 0.333333333333333
    //       3.14159265358979 <> 3.14159265358979
    
    
    

    In questo caso, si può eseguire correttamente una sequenza di andata e ritorno dei valori utilizzando la stringa di formato numerico standard "R" per mantenere la precisione completa dei valori Double, come illustrato di seguito.

    
    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Doubles.dat");
          Double[] values = { 2.2/1.01, 1.0/3, Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) 
             sw.Write("{0:R}{1}", values[ctr], ctr < values.Length - 1 ? "|" : "" );
    
          sw.Close();
    
          Double[] restoredValues = new Double[values.Length];
          StreamReader sr = new StreamReader(@".\Doubles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Double.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.17821782178218 = 2.17821782178218
    //       0.333333333333333 = 0.333333333333333
    //       3.14159265358979 = 3.14159265358979
    
    
    
  • I valori Single hanno una precisione inferiore rispetto a quella dei valori Double. Un valore Single convertito in uno apparentemente equivalente Double spesso non è equivalente al valore Double a causa delle differenze di precisione. Nell'esempio seguente, il risultato delle operazioni di divisione identiche viene assegnato ad un valore Double e ad un valore Single. Dopo che il valore Single viene convertito nel tipo Double, un confronto dei due valori mostra che essi sono diversi.

    
    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
    
    
    

    Per evitare questo problema, utilizzare Double invece che il tipo di dati Single, o utilizzare il metodo Round in modo che entrambi i valori abbiano la stessa precisione.

Inoltre, il risultato delle operazioni aritmetiche e di assegnazione con valori Double può differire leggermente a seconda della piattaforma a causa della perdita di precisione del tipo Double. Ad esempio, il risultato dell'assegnazione di un valore Double letterale potrebbe essere diverso nelle versioni a 32 bit e a 64 bit di .NET Framework. Nell'esempio riportato di seguito viene illustrata questa differenza quando il valore letterale -4.42330604244772E-305 e una variabile il cui valore è -4.42330604244772E-305 vengono assegnati a una variabile Double. Si noti che il risultato del metodo Parse(String) in questo caso non subisce una perdita di precisione.


double value = -4.42330604244772E-305;

double fromLiteral = -4.42330604244772E-305;
double fromVariable = value;
double fromParse = Double.Parse("-4.42330604244772E-305");

Console.WriteLine("Double value from literal: {0,29:R}", fromLiteral);
Console.WriteLine("Double value from variable: {0,28:R}", fromVariable);
Console.WriteLine("Double value from Parse method: {0,24:R}", fromParse);      
// On 32-bit versions of the .NET Framework, the output is:
//    Double value from literal:        -4.42330604244772E-305
//    Double value from variable:       -4.42330604244772E-305
//    Double value from Parse method:   -4.42330604244772E-305
//
// On other versions of the .NET Framework, the output is:
//    Double value from literal:      -4.4233060424477198E-305
//    Double value from variable:     -4.4233060424477198E-305
//    Double value from Parse method:   -4.42330604244772E-305      


Test dell'uguaglianza

Per essere considerati uguali, due valori Double devono rappresentare valori identici. Tuttavia, a causa delle differenze di precisione tra valori, o a causa di una perdita di precisione da parte di uno o di entrambi i valori, i valori in virgola mobile che ci si aspetta essere identici spesso risultano essere differenti a causa delle differenze nelle rispettive cifre meno significative. Di conseguenza, si chiama il metodo Equals per determinare se due valori sono uguali, o si chiama il metodo CompareTo per determinare la relazione tra due valori Double, che spesso producono risultati imprevisti. Questo è evidente nell'esempio seguente, in cui due valori apparentemente uguali Double risultano essere diversi in quanto il primo ha 15 cifre di precisione, mentre il secondo ne ha 17.


using System;

public class Example
{
   public static void Main()
   {
      double value1 = .333333333333333;
      double value2 = 1.0/3;
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
   }
}
// The example displays the following output:
//        0.333333333333333 = 0.33333333333333331: False


I valori calcolati che seguono percorsi di codice differenti e che sono manipolati diversamente risultano spesso essere differenti. Nell'esempio seguente, un valore Double è elevato al quadrato, quindi viene calcolata la radice quadrata per ripristinare il valore originale. Un secondo Double è moltiplicato per 3,51 ed è elevato alla seconda prima di dividere per 3,51 la radice quadrata del risultato per ripristinare il valore originale. Anche se i due valori sembrano essere identici, una chiamata al metodo Equals(Double) indica che non lo sono. Usare la stringa di formato standard "R" per restituire una stringa di risultato che mostra tutte le cifre significative di ciascun valore Double mostra che il secondo valore è 0,0000000000001 più piccolo del primo.


using System;

public class Example
{
   public static void Main()
   {
      double value1 = 100.10142;
      value1 = Math.Sqrt(Math.Pow(value1, 2));
      double value2 = Math.Pow(value1 * 3.51, 2);
      value2 = Math.Sqrt(value2) / 3.51;
      Console.WriteLine("{0} = {1}: {2}\n", 
                        value1, value2, value1.Equals(value2)); 
      Console.WriteLine("{0:R} = {1:R}", value1, value2); 
   }
}
// The example displays the following output:
//    100.10142 = 100.10142: False
//    
//    100.10142 = 100.10141999999999


Nei casi in cui una perdita di precisione potrebbe influire sul risultato di un confronto, è possibile adottare una delle seguenti alternative alla chiamata del metodo CompareTo o Equals:

  • Chiamare il metodo Math.Round per assicurarsi che entrambi i valori abbiano la stessa precisione. Nell'esempio seguente viene modificato un esempio precedente per utilizzare questo approccio in modo che due valori frazionari siano equivalenti.

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          double value1 = .333333333333333;
          double value2 = 1.0/3;
          int precision = 7;
          value1 = Math.Round(value1, precision);
          value2 = 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
    
    
    

    Si noti, tuttavia, che il problema di precisione si applica comunque all'arrotondamento dei valori sul punto medio. Per ulteriori informazioni, vedere il metodo Math.Round(Double, Int32, MidpointRounding).

  • Test di uguaglianza approssimativa anziché di uguaglianza. A tale scopo occorre definire una cifra assoluta da cui i due valori possono differire ma comunque essere uguali, altrimenti va definita una quantità da cui il valore più piccolo può divergere dal valore più grande.

    Nota di avvisoAttenzione

    Double.Epsilon talvolta viene utilizzato come una misura assoluta della distanza tra due valori Double durante il test di uguaglianza. Tuttavia, Double.Epsilon misura possibile il valore più piccolo che può essere aggiunto, o essere sottratto da, Double il cui valore è zero. Per la maggior parte dei valori positivi e negativi Double, il valore del segno Double.Epsilon è troppo piccolo per essere rilevato. Di conseguenza, ad eccezione dei valori che sono zero, è consigliabile evitare il relativo utilizzo nei test di uguaglianza.

    Nell'esempio seguente viene utilizzato quest'ultimo approccio per definire un metodo IsApproximatelyEqual che verifica la relativa differenza tra i due valori. Vengono inoltre confrontati il risultato delle chiamate al metodo IsApproximatelyEqual e al metodo Equals(Double).

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          double one1 = .1 * 10;
          double one2 = 0;
          for (int ctr = 1; ctr <= 10; ctr++)
             one2 += .1;
    
          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, .000000001));   
       }
    
       static bool IsApproximatelyEqual(double value1, double value2, double 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 = 0.99999999999999989: False
    //       1 is approximately equal to 0.99999999999999989: True
    
    
    

Valori a virgola mobile ed eccezioni

A differenza delle operazioni con i tipi integrali, che generano eccezioni nei casi di overflow o di operazioni non valide come la divisione per zero, le operazioni con i valori in virgola mobile non generano eccezioni. Invece, in situazioni eccezionali, il risultato di un'operazione in virgola mobile è zero, infinito positivo, infinito negativo o non un numero (NaN):

  • Se il risultato di un'operazione in virgola mobile è troppo piccolo per il formato di destinazione, il risultato è zero. Questa situazione può verificarsi quando vengono moltiplicati due numeri molto piccoli, come illustrato di seguito.

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 1.1632875981534209e-225;
          Double value2 = 9.1642346778e-175;
          Double result = value1 * value2;
          Console.WriteLine("{0} * {1} = {2}", value1, value2, result);
          Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0));
       }
    }
    // The example displays the following output:
    //       1.16328759815342E-225 * 9.1642346778E-175 = 0
    //       0 = 0: True
    
    
    
  • Se l'ordine di grandezza del risultato di un'operazione in virgola eccede l'intervallo del formato di destinazione, il risultato dell'operazione è PositiveInfinity o NegativeInfinity, a seconda del segno del risultato. Il risultato di un'operazione che supera Double.MaxValue è PositiveInfinity e il risultato di un'operazione che supera Double.MinValue è NegativeInfinity, come illustrato dall'esempio seguente.

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 4.565e153;
          Double value2 = 6.9375e172;
          Double result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Double.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}\n", 
                            Double.IsNegativeInfinity(result));
    
          value1 = -value1;
          result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Double.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}", 
                            Double.IsNegativeInfinity(result));
       }
    }                                                                 
    
    // The example displays the following output:
    //       PositiveInfinity: True
    //       NegativeInfinity: False
    //       
    //       PositiveInfinity: False
    //       NegativeInfinity: True
    
    
    

    Anche PositiveInfinity deriva da una divisione per zero con un dividendo positivo e NegativeInfinity deriva da una divisione per zero con un dividendo negativo.

  • Se l'operazione in virgola mobile non è valida, il risultato dell'operazione è NaN. Ad esempio, NaN deriva dalle seguenti operazioni:

  • Qualsiasi operazione in virgola mobile con un input non valido. Ad esempio, chiamare il metodo Math.Sqrt con un valore negativo restituisce NaN, come anche chiamare il metodo Math.Acos con un valore maggiore o minore di uno con segno negativo.

  • Qualsiasi operazione con un argomento il cui valore è Double.NaN.

Funzionalità a virgola mobile

La struttura Double e i tipi correlati forniscono metodi per eseguire operazioni nelle aree seguenti:

  • Confronto di valori . È possibile chiamare il metodo Equals per determinare se due valori Double sono uguali, o il metodo CompareTo per determinare la relazione tra due valori.

    La struttura Double supporta inoltre un set completo di operatori di confronto. Ad esempio, è possibile verificare l'uguaglianza e la disuguaglianza, o determinare se un valore è superiore o uguale a un altro. Se uno degli operandi è un tipo numerico diverso da Double, esso viene convertito in Double prima di eseguire il confronto.

    Nota di avvisoAttenzione

    A causa delle differenze di precisione, due valori Double che ci si aspetta essere uguali possono risultare diversi, fatto che influisce sul risultato del confronto. Vedere la sezione Test di uguaglianza per ulteriori informazioni sul confronto tra due valori Double.

    È inoltre possibile chiamare i metodi IsNaN, IsInfinity, IsPositiveInfinity e IsNegativeInfinity per testare questi valori speciali.

  • Operazioni matematiche . Le operazioni aritmetiche comuni, come addizione, sottrazione, moltiplicazione e divisione, vengono implementate dai compilatori di linguaggio e dalle istruzioni del Common Intermediate Language (CIL), anziché dai metodi Double. Se uno degli operandi in un'operazione matematica è un tipo numerico diverso da Double, esso viene convertito in Double prima di eseguire l'operazione. Il risultato dell'operazione è anche un valore Double.

    Altre operazioni matematiche possono essere eseguite chiamando i metodi static (Shared in Visual Basic) nella classe System.Math. Include metodi aggiuntivi di utilizzo comune per operazioni aritmetiche (ad esempio Math.Abs, Math.Sign e Math.Sqrt), geometriche (ad esempio Math.Cos e Math.Sin) e per il calcolo (ad esempio Math.Log).

    È anche possibile modificare singoli bit in un valore Double. Il metodo BitConverter.DoubleToInt64Bits conserva lo schema di bit di un valore Double in un intero a 64 bit. Il metodo BitConverter.GetBytes(Double) restituisce il relativo schema di bit in un array di byte.

  • Arrotondamento . L'arrotondamento viene spesso utilizzato come tecnica di riduzione dell'impatto delle differenze tra i valori causate da problemi di rappresentazione e precisione in virgola mobile. È possibile arrotondate un valore Double chiamando il metodo Math.Round.

  • Formattazione . È possibile convertire un valore Double nella relativa rappresentazione in forma di stringa chiamando il metodo ToString o utilizzando la funzionalità di formattazione composita. Per informazioni su come formattare stringhe per controllare la rappresentazione in forma di stringa di valori in virgola mobile, vedere gli argomenti Stringhe di formato numerico personalizzate e Stringhe di formato numerico standard.

  • Analisi delle stringhe . È possibile convertire la rappresentazione in forma di stringa di un valore in virgola mobile in un valore Double chiamando il metodo Parse o TryParse. Se l'operazione di analisi ha esito negativo, il metodo Parse genera un'eccezione, mentre il metodo TryParse restituisce false.

  • Conversione di tipi . La struttura Double fornisce un'implementazione esplicita dell'interfaccia per l'interfaccia IConvertible, la quale supporta la conversione tra due tipi di dati standard di .NET Framework. I compilatori di linguaggi supportano anche la conversione implicita dei valori di tutti gli altri tipi numerici standard per i valori Double. La conversione di un valore di qualsiasi tipo numerico standard a Double è una conversione di ampliamento e non richiede all'utente un operatore di conversione di tipo o un metodo di conversione.

    Comunque, la conversione dei valori Int64 e Single può comportare una perdita di precisione. Nella tabella seguente sono elencate le differenze nella precisione per ciascuno dei seguenti tipi:

    Tipo

    Precisione massima

    Precisione interna

    Double

    15

    17

    Int64

    19 cifre decimali

    19 cifre decimali

    Single

    7 cifre decimali

    9 cifre decimali

    Il problema di precisione affligge più frequentemente i valori Single che vengono convertiti in valori Double. Nell'esempio seguente, due valori prodotti da operazioni di divisione identiche risultano diversi perché uno dei valori è un valore in virgola mobile a singola precisione convertito in Double.

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value = .1;
          Double result1 = value * 10;
          Double result2 = 0;
          for (int ctr = 1; ctr <= 10; ctr++)
             result2 += value;
    
          Console.WriteLine(".1 * 10:           {0:R}", result1);
          Console.WriteLine(".1 Added 10 times: {0:R}", result2);
       }
    }
    // The example displays the following output:
    //       .1 * 10:           1
    //       .1 Added 10 times: 0.99999999999999989
    
    
    

Nell'esempio di codice riportato di seguito viene illustrato l'utilizzo di Double.


	// The Temperature class stores the temperature as a Double
	// and delegates most of the functionality to the Double
	// implementation.
	public class Temperature : IComparable, IFormattable 
    {
		// IComparable.CompareTo implementation.
		public int CompareTo(object obj) {
            if (obj == null) return 1;

			Temperature temp = obj as Temperature;
            if (obj != null) 
				return m_value.CompareTo(temp.m_value);
			else
     			throw new ArgumentException("object is not a Temperature");	
		}

		// IFormattable.ToString implementation.
		public string ToString(string format, IFormatProvider provider) {
			if( format != null ) {
				if( format.Equals("F") ) {
					return String.Format("{0}'F", this.Value.ToString());
				}
				if( format.Equals("C") ) {
					return String.Format("{0}'C", this.Celsius.ToString());
				}
			}

			return m_value.ToString(format, provider);
		}

		// Parses the temperature from a string in the form
		// [ws][sign]digits['F|'C][ws]
		public static Temperature Parse(string s, NumberStyles styles, IFormatProvider provider) {
			Temperature temp = new Temperature();

			if( s.TrimEnd(null).EndsWith("'F") ) {
				temp.Value = Double.Parse( s.Remove(s.LastIndexOf('\''), 2), styles, provider);
			}
			else if( s.TrimEnd(null).EndsWith("'C") ) {
				temp.Celsius = Double.Parse( s.Remove(s.LastIndexOf('\''), 2), styles, provider);
			}
			else {
				temp.Value = Double.Parse(s, styles, provider);
			}

			return temp;
		}

		// The value holder
		protected double m_value;

		public double Value {
			get {
				return m_value;
			}
			set {
				m_value = value;
			}
		}

		public double Celsius {
			get {
				return (m_value-32.0)/1.8;
			}
			set {
				m_value = 1.8*value+32.0;
			}
		}
	}


.NET Framework

Supportato in: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supportato in: 4, 3.5 SP1

Libreria di classi portabile

Supportato in: Libreria di classi portabile

.NET per applicazioni Windows Store

Supportato in: Windows 8

.NET per applicazioni Windows Phone

Supportato in: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (ruoli di base del server non supportati), Windows Server 2008 R2 (ruoli di base del server supportati con SP1 o versione successiva, Itanium non supportato)

.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema di .NET Framework.

Tutti i membri di questo tipo sono thread-safe. I membri che sembrano modificare lo stato dell'istanza restituiscono in realtà una nuova istanza inizializzata con il nuovo valore. Come con qualsiasi altro tipo, le operazioni di lettura e scrittura su una variabile condivisa che contiene un'istanza di questo tipo devono essere protette da un blocco per garantire che siano thread-safe.

Nota di avvisoAttenzione

L'assegnazione di un'istanza di questo tipo non è thread-safe su tutte le piattaforme hardware perché la rappresentazione binaria di tale istanza potrebbe essere troppo estesa per l'assegnazione in un'unica operazione atomica.

Aggiunte alla community

AGGIUNGI
Mostra:
© 2015 Microsoft