Double Struktura

Definicja

Reprezentuje liczbę zmiennoprzecinkową o podwójnej precyzji.

public value class double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
public value class double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, ISpanFormattable
public value class double : IComparable<double>, IConvertible, IEquatable<double>, IParsable<double>, ISpanParsable<double>, System::Numerics::IAdditionOperators<double, double, double>, System::Numerics::IAdditiveIdentity<double, double>, System::Numerics::IBinaryFloatingPointIeee754<double>, System::Numerics::IBinaryNumber<double>, System::Numerics::IBitwiseOperators<double, double, double>, System::Numerics::IComparisonOperators<double, double>, System::Numerics::IDecrementOperators<double>, System::Numerics::IDivisionOperators<double, double, double>, System::Numerics::IEqualityOperators<double, double>, System::Numerics::IExponentialFunctions<double>, System::Numerics::IFloatingPoint<double>, System::Numerics::IFloatingPointIeee754<double>, System::Numerics::IHyperbolicFunctions<double>, System::Numerics::IIncrementOperators<double>, System::Numerics::ILogarithmicFunctions<double>, System::Numerics::IMinMaxValue<double>, System::Numerics::IModulusOperators<double, double, double>, System::Numerics::IMultiplicativeIdentity<double, double>, System::Numerics::IMultiplyOperators<double, double, double>, System::Numerics::INumber<double>, System::Numerics::INumberBase<double>, System::Numerics::IPowerFunctions<double>, System::Numerics::IRootFunctions<double>, System::Numerics::ISignedNumber<double>, System::Numerics::ISubtractionOperators<double, double, double>, System::Numerics::ITrigonometricFunctions<double>, System::Numerics::IUnaryNegationOperators<double, double>, System::Numerics::IUnaryPlusOperators<double, double>
public value class double : IComparable, IConvertible, IFormattable
public value class double : IComparable, IComparable<double>, IEquatable<double>, IFormattable
public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
public readonly struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
public readonly struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, ISpanFormattable
public readonly struct Double : IComparable<double>, IConvertible, IEquatable<double>, IParsable<double>, ISpanParsable<double>, System.Numerics.IAdditionOperators<double,double,double>, System.Numerics.IAdditiveIdentity<double,double>, System.Numerics.IBinaryFloatingPointIeee754<double>, System.Numerics.IBinaryNumber<double>, System.Numerics.IBitwiseOperators<double,double,double>, System.Numerics.IComparisonOperators<double,double>, System.Numerics.IDecrementOperators<double>, System.Numerics.IDivisionOperators<double,double,double>, System.Numerics.IEqualityOperators<double,double>, System.Numerics.IExponentialFunctions<double>, System.Numerics.IFloatingPoint<double>, System.Numerics.IFloatingPointIeee754<double>, System.Numerics.IHyperbolicFunctions<double>, System.Numerics.IIncrementOperators<double>, System.Numerics.ILogarithmicFunctions<double>, System.Numerics.IMinMaxValue<double>, System.Numerics.IModulusOperators<double,double,double>, System.Numerics.IMultiplicativeIdentity<double,double>, System.Numerics.IMultiplyOperators<double,double,double>, System.Numerics.INumber<double>, System.Numerics.INumberBase<double>, System.Numerics.IPowerFunctions<double>, System.Numerics.IRootFunctions<double>, System.Numerics.ISignedNumber<double>, System.Numerics.ISubtractionOperators<double,double,double>, System.Numerics.ITrigonometricFunctions<double>, System.Numerics.IUnaryNegationOperators<double,double>, System.Numerics.IUnaryPlusOperators<double,double>
[System.Serializable]
public struct Double : IComparable, IConvertible, IFormattable
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
public struct Double : IComparable, IComparable<double>, IEquatable<double>, IFormattable
type double = struct
    interface IConvertible
    interface IFormattable
type double = struct
    interface IConvertible
    interface ISpanFormattable
    interface IFormattable
type double = struct
    interface IConvertible
    interface IFormattable
    interface IParsable<double>
    interface ISpanFormattable
    interface ISpanParsable<double>
    interface IAdditionOperators<double, double, double>
    interface IAdditiveIdentity<double, double>
    interface IBinaryFloatingPointIeee754<double>
    interface IBinaryNumber<double>
    interface IBitwiseOperators<double, double, double>
    interface IComparisonOperators<double, double>
    interface IEqualityOperators<double, double>
    interface IDecrementOperators<double>
    interface IDivisionOperators<double, double, double>
    interface IIncrementOperators<double>
    interface IModulusOperators<double, double, double>
    interface IMultiplicativeIdentity<double, double>
    interface IMultiplyOperators<double, double, double>
    interface INumber<double>
    interface INumberBase<double>
    interface ISubtractionOperators<double, double, double>
    interface IUnaryNegationOperators<double, double>
    interface IUnaryPlusOperators<double, double>
    interface IExponentialFunctions<double>
    interface IFloatingPoint<double>
    interface ISignedNumber<double>
    interface IFloatingPointIeee754<double>
    interface IHyperbolicFunctions<double>
    interface ILogarithmicFunctions<double>
    interface IPowerFunctions<double>
    interface IRootFunctions<double>
    interface ITrigonometricFunctions<double>
    interface IMinMaxValue<double>
[<System.Serializable>]
type double = struct
    interface IFormattable
    interface IConvertible
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type double = struct
    interface IFormattable
    interface IConvertible
type double = struct
    interface IFormattable
Public Structure Double
Implements IComparable, IComparable(Of Double), IConvertible, IEquatable(Of Double), IFormattable
Public Structure Double
Implements IComparable, IComparable(Of Double), IConvertible, IEquatable(Of Double), ISpanFormattable
Public Structure Double
Implements IAdditionOperators(Of Double, Double, Double), IAdditiveIdentity(Of Double, Double), IBinaryFloatingPointIeee754(Of Double), IBinaryNumber(Of Double), IBitwiseOperators(Of Double, Double, Double), IComparable(Of Double), IComparisonOperators(Of Double, Double), IConvertible, IDecrementOperators(Of Double), IDivisionOperators(Of Double, Double, Double), IEqualityOperators(Of Double, Double), IEquatable(Of Double), IExponentialFunctions(Of Double), IFloatingPoint(Of Double), IFloatingPointIeee754(Of Double), IHyperbolicFunctions(Of Double), IIncrementOperators(Of Double), ILogarithmicFunctions(Of Double), IMinMaxValue(Of Double), IModulusOperators(Of Double, Double, Double), IMultiplicativeIdentity(Of Double, Double), IMultiplyOperators(Of Double, Double, Double), INumber(Of Double), INumberBase(Of Double), IParsable(Of Double), IPowerFunctions(Of Double), IRootFunctions(Of Double), ISignedNumber(Of Double), ISpanParsable(Of Double), ISubtractionOperators(Of Double, Double, Double), ITrigonometricFunctions(Of Double), IUnaryNegationOperators(Of Double, Double), IUnaryPlusOperators(Of Double, Double)
Public Structure Double
Implements IComparable, IConvertible, IFormattable
Public Structure Double
Implements IComparable, IComparable(Of Double), IEquatable(Of Double), IFormattable
Dziedziczenie
Double
Atrybuty
Implementuje
IComparable IComparable<Double> IConvertible IEquatable<Double> IFormattable ISpanFormattable IComparable<TOther> IComparable<TSelf> IEquatable<TOther> IEquatable<TSelf> IParsable<Double> IParsable<TSelf> ISpanParsable<Double> ISpanParsable<TSelf> IAdditionOperators<Double,Double,Double> IAdditionOperators<TSelf,TSelf,TSelf> IAdditiveIdentity<Double,Double> IAdditiveIdentity<TSelf,TSelf> IBinaryFloatingPointIeee754<Double> IBinaryNumber<Double> IBinaryNumber<TSelf> IBitwiseOperators<Double,Double,Double> IBitwiseOperators<TSelf,TSelf,TSelf> IComparisonOperators<Double,Double> IComparisonOperators<TSelf,TSelf> IDecrementOperators<Double> IDecrementOperators<TSelf> IDivisionOperators<Double,Double,Double> IDivisionOperators<TSelf,TSelf,TSelf> IEqualityOperators<Double,Double> IEqualityOperators<TSelf,TOther> IEqualityOperators<TSelf,TSelf> IExponentialFunctions<Double> IExponentialFunctions<TSelf> IFloatingPoint<Double> IFloatingPoint<TSelf> IFloatingPointIeee754<Double> IFloatingPointIeee754<TSelf> IHyperbolicFunctions<Double> IHyperbolicFunctions<TSelf> IIncrementOperators<Double> IIncrementOperators<TSelf> ILogarithmicFunctions<Double> ILogarithmicFunctions<TSelf> IMinMaxValue<Double> IModulusOperators<Double,Double,Double> IModulusOperators<TSelf,TSelf,TSelf> IMultiplicativeIdentity<Double,Double> IMultiplicativeIdentity<TSelf,TSelf> IMultiplyOperators<Double,Double,Double> IMultiplyOperators<TSelf,TSelf,TSelf> INumber<Double> INumber<TSelf> INumberBase<Double> INumberBase<TSelf> IPowerFunctions<Double> IPowerFunctions<TSelf> IRootFunctions<Double> IRootFunctions<TSelf> ISignedNumber<Double> ISignedNumber<TSelf> ISubtractionOperators<Double,Double,Double> ISubtractionOperators<TSelf,TSelf,TSelf> ITrigonometricFunctions<Double> ITrigonometricFunctions<TSelf> IUnaryNegationOperators<Double,Double> IUnaryNegationOperators<TSelf,TSelf> IUnaryPlusOperators<Double,Double> IUnaryPlusOperators<TSelf,TSelf>

Przykłady

Poniższy przykład kodu ilustruje użycie elementu Double:

// The Temperature class stores the temperature as a Double
// and delegates most of the functionality to the Double 
// implementation.
public ref class Temperature: public IComparable, public IFormattable
{
   // IComparable.CompareTo implementation.
public:
   virtual int CompareTo( Object^ obj )
   {
      if (obj == nullptr) return 1;
      
      if (dynamic_cast<Temperature^>(obj) )
      {
         Temperature^ temp = (Temperature^)(obj);
         return m_value.CompareTo( temp->m_value );
      }
      throw gcnew ArgumentException( "object is not a Temperature" );
   }

   // IFormattable.ToString implementation.
   virtual String^ ToString( String^ format, IFormatProvider^ provider )
   {
      if ( format != nullptr )
      {
         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]
   static Temperature^ Parse( String^ s, NumberStyles styles, IFormatProvider^ provider )
   {
      Temperature^ temp = gcnew Temperature;

      if ( s->TrimEnd(nullptr)->EndsWith( "'F" ) )
      {
         temp->Value = Double::Parse( s->Remove( s->LastIndexOf( '\'' ), 2 ), styles, provider );
      }
      else
      if ( s->TrimEnd(nullptr)->EndsWith( "'C" ) )
      {
         temp->Celsius = Double::Parse( s->Remove( s->LastIndexOf( '\'' ), 2 ), styles, provider );
      }
      else
      {
         temp->Value = Double::Parse( s, styles, provider );
      }
      return temp;
   }

protected:
   double m_value;

public:
   property double Value 
   {
      double get()
      {
         return m_value;
      }

      void set( double value )
      {
         m_value = value;
      }
   }

   property double Celsius 
   {
      double get()
      {
         return (m_value - 32.0) / 1.8;
      }

      void set( double value )
      {
         m_value = 1.8 * value + 32.0;
      }
   }
};
// 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;
        }
    }
}
// The Temperature class stores the temperature as a Double
// and delegates most of the functionality to the Double
// implementation.
type Temperature() =
    member val Value = 0. with get, set

    member this.Celsius
        with get () = (this.Value - 32.) / 1.8
        and set (value) =
            this.Value <- 1.8 * value + 32.

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

        if s.TrimEnd(null).EndsWith "'F" then
            temp.Value <- Double.Parse(s.Remove(s.LastIndexOf '\'', 2), styles, provider)
        elif s.TrimEnd(null).EndsWith "'C" then
            temp.Celsius <- Double.Parse(s.Remove(s.LastIndexOf '\'', 2), styles, provider)
        else
            temp.Value <- Double.Parse(s, styles, provider)
        temp

    interface IComparable with
        // IComparable.CompareTo implementation.
        member this.CompareTo(obj: obj) =
            match obj with 
            | null -> 1
            | :? Temperature as temp ->
                this.Value.CompareTo temp.Value
            | _ ->
                invalidArg "obj" "object is not a Temperature"

    interface IFormattable with
        // IFormattable.ToString implementation.
        member this.ToString(format: string, provider: IFormatProvider) =
            match format with
            | "F" ->
                $"{this.Value}'F"
            | "C" ->
                $"{this.Celsius}'C"
            | _ ->
                this.Value.ToString(format, provider)
' Temperature class stores the value as Double
' and delegates most of the functionality 
' to the Double implementation.
Public Class Temperature
    Implements IComparable, IFormattable

    Public Overloads Function CompareTo(ByVal obj As Object) As Integer _
        Implements IComparable.CompareTo

        If TypeOf obj Is Temperature Then
            Dim temp As Temperature = CType(obj, Temperature)

            Return m_value.CompareTo(temp.m_value)
        End If

        Throw New ArgumentException("object is not a Temperature")
    End Function

    Public Overloads Function ToString(ByVal format As String, ByVal provider As IFormatProvider) As String _
        Implements IFormattable.ToString

        If Not (format Is Nothing) Then
            If format.Equals("F") Then
                Return [String].Format("{0}'F", Me.Value.ToString())
            End If
            If format.Equals("C") Then
                Return [String].Format("{0}'C", Me.Celsius.ToString())
            End If
        End If

        Return m_value.ToString(format, provider)
    End Function

    ' Parses the temperature from a string in form
    ' [ws][sign]digits['F|'C][ws]
    Public Shared Function Parse(ByVal s As String, ByVal styles As NumberStyles, ByVal provider As IFormatProvider) As Temperature
        Dim temp As New Temperature()

        If s.TrimEnd(Nothing).EndsWith("'F") Then
            temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider)
        Else
            If s.TrimEnd(Nothing).EndsWith("'C") Then
                temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider)
            Else
                temp.Value = Double.Parse(s, styles, provider)
            End If
        End If
        Return temp
    End Function

    ' The value holder
    Protected m_value As Double

    Public Property Value() As Double
        Get
            Return m_value
        End Get
        Set(ByVal Value As Double)
            m_value = Value
        End Set
    End Property

    Public Property Celsius() As Double
        Get
            Return (m_value - 32) / 1.8
        End Get
        Set(ByVal Value As Double)
            m_value = Value * 1.8 + 32
        End Set
    End Property
End Class

Uwagi

Typ Double wartości reprezentuje liczbę 64-bitową o podwójnej precyzji z wartościami ujemnymi 1,7976931348623232e308 do dodatniej 1,7976931348623232308, a także dodatnim lub ujemnym zerem, PositiveInfinity, NegativeInfinityi nie liczbą (NaN). Ma ona reprezentować wartości, które są bardzo duże (takie jak odległości między planetami lub galaktykami) lub bardzo małe (takie jak masa molekularna substancji w kilogramach) i które często są nieprecyzyjne (takie jak odległość od ziemi do innego układu słonecznego). Typ Double jest zgodny z normą IEC 60559:1989 (IEEE 754) dla binarnej arytmetyki zmiennoprzecinkowych.

Ten temat składa się z następujących sekcji:

Reprezentacja liczb zmiennoprzecinkowych i precyzja

Double Typ danych przechowuje wartości zmiennoprzecinkowe o podwójnej precyzji w formacie binarnym 64-bitowym, jak pokazano w poniższej tabeli:

Część Bity
Znakowe lub mantissa 0-51
Wykładnik 52-62
Znak (0 = dodatnie, 1 = ujemne) 63

Podobnie jak ułamki dziesiętne nie są w stanie dokładnie reprezentować niektórych wartości ułamkowych (takich jak 1/3 lub Math.PI), ułamki binarne nie mogą reprezentować niektórych wartości ułamkowych. Na przykład 1/10, który jest reprezentowany dokładnie przez .1 jako ułamek dziesiętny, jest reprezentowany przez .001100110011 jako ułamek binarny, ze wzorcem "0011" powtarzającym się do nieskończoności. W takim przypadku wartość zmiennoprzecinkowa zapewnia nieprecyzyjne przedstawienie liczby, którą reprezentuje. Wykonywanie dodatkowych operacji matematycznych na oryginalnej wartości zmiennoprzecinkowej często ma tendencję do zwiększania jego braku precyzji. Jeśli na przykład porównujemy wynik mnożenia wartości .1 o 10 i dodamy wartość .1 do .1 dziewięć razy, zobaczymy, że dodatek, ponieważ obejmował osiem kolejnych operacji, wygenerował mniej precyzyjny wynik. Należy pamiętać, że ta rozbieżność jest widoczna tylko wtedy, gdy wyświetlamy dwie Double wartości przy użyciu standardowego ciągu formatu liczbowego "R", który w razie potrzeby wyświetla wszystkie 17 cyfr dokładności obsługiwanej przez Double typ.

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
let value = 0.1
let result1 = value * 10.
let mutable result2 = 0.
for i = 1 to 10 do
    result2 <- result2 + value

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

Ponieważ niektóre liczby nie mogą być reprezentowane dokładnie jako wartości binarne ułamkowe, liczby zmiennoprzecinkowe mogą tylko przybliżone liczby rzeczywiste.

Wszystkie liczby zmiennoprzecinkowe mają również ograniczoną liczbę cyfr znaczących, co określa również, jak dokładnie wartość zmiennoprzecinkowa przybliża liczbę rzeczywistą. Wartość Double ma maksymalnie 15 cyfr dziesiętnych dokładności, chociaż maksymalnie 17 cyfr jest utrzymywanych wewnętrznie. Oznacza to, że niektóre operacje zmiennoprzecinkowe mogą nie mieć precyzji zmiany wartości zmiennoprzecinkowej. Poniższy przykład stanowi ilustrację. Definiuje bardzo dużą wartość zmiennoprzecinkową, a następnie dodaje do niej produkt Double.Epsilon i jeden czworokąt. Jednak produkt jest zbyt mały, aby zmodyfikować oryginalną wartość zmiennoprzecinkową. Jego najmniej znacząca cyfra jest tysięczna, natomiast najważniejszą cyfrą w produkcie jest 10–309.

using System;

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

let value = 123456789012.34567
let additional = Double.Epsilon * 1e15
printfn $"{value} + {additional} = {value + additional}"
// The example displays the following output:
//    123456789012.346 + 4.94065645841247E-309 = 123456789012.346
Module Example
   Public Sub Main()
      Dim value As Double = 123456789012.34567
      Dim additional As Double = Double.Epsilon * 1e15
      Console.WriteLine("{0} + {1} = {2}", value, additional, 
                                           value + additional)
   End Sub
End Module
' The example displays the following output:
'   123456789012.346 + 4.94065645841247E-309 = 123456789012.346

Ograniczona precyzja liczby zmiennoprzecinkowych ma kilka konsekwencji:

  • Dwie liczby zmiennoprzecinkowe, które wydają się równe określonej precyzji, mogą nie być równe, ponieważ ich najmniej znaczące cyfry są różne. W poniższym przykładzie liczba jest dodawana razem, a ich suma jest porównywana z oczekiwaną sumą. Chociaż dwie wartości wydają się być takie same, wywołanie Equals metody wskazuje, że nie są.

    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).
    
    let values = [ 10.0; 2.88; 2.88; 2.88; 9.0 ]
    let result = 27.64
    let total = List.sum values
    
    if total.Equals result then
        printfn "The sum of the values equals the total."
    else
        printfn $"The sum of the values ({total}) does not equal the 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).
    
    Module Example
       Public Sub Main()
          Dim values() As Double = { 10.0, 2.88, 2.88, 2.88, 9.0 }
          Dim result As Double = 27.64
          Dim total As Double
          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 (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).
    

    Jeśli zmienisz elementy formatu w instrukcji z {0} i na {0:R} i {1} i{1:R}, aby wyświetlić wszystkie znaczące cyfry dwóch Double wartości, jasne jest, że te dwie wartości są nierówne z powodu utraty dokładności podczas operacji dodawania.Console.WriteLine(String, Object, Object) W takim przypadku problem można rozwiązać, wywołując Math.Round(Double, Int32) metodę , aby zaokrąglić Double wartości do żądanej dokładności przed wykonaniem porównania.

  • Operacja matematyczna lub porównawcza używająca liczby zmiennoprzecinkowej może nie zwracać tego samego wyniku, jeśli jest używana liczba dziesiętna, ponieważ liczba zmiennoprzecinkowa binarna może nie być równa liczbie dziesiętnej. W poprzednim przykładzie pokazano to, wyświetlając wynik mnożenia wartości .1 przez 10 i dodając wartość .1 razy.

    Gdy dokładność operacji liczbowych z wartościami ułamkowymi jest ważna, można użyć Decimal typu zamiast Double typu. Gdy dokładność operacji liczbowych z wartościami całkowitymi wykracza poza zakres Int64 typów lub UInt64 jest ważna, użyj BigInteger typu .

  • Wartość może nie być zaokrąglona, jeśli jest zaangażowana liczba zmiennoprzecinkowa. Wartość mówi się, że w przypadku rundy, jeśli operacja konwertuje oryginalną liczbę zmiennoprzecinkową na inną formę, operacja odwrotna przekształca przekonwertowany formularz z powrotem na liczbę zmiennoprzecinkową, a ostateczna liczba zmiennoprzecinkowa nie jest równa oryginalnej liczbie zmiennoprzecinkowej. Runda może zakończyć się niepowodzeniem, ponieważ co najmniej jedna cyfra znacząca zostanie utracona lub zmieniona w konwersji. W poniższym przykładzie trzy Double wartości są konwertowane na ciągi i zapisywane w pliku. Jak pokazuje dane wyjściowe, mimo że wartości wydają się być identyczne, przywrócone wartości nie są równe oryginalnym wartościom.

    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
    
    open System
    open System.IO
    
    let values = [ 2.2 / 1.01; 1. / 3.; Math.PI ]
    
    using (new StreamWriter(@".\Doubles.dat")) (fun sw ->
        for i = 0 to values.Length - 1 do
            sw.Write(string values[i])
            if i <> values.Length - 1 then
                sw.Write "|")
    
    using (new StreamReader(@".\Doubles.dat")) (fun sr ->
        let temp = sr.ReadToEnd()
        let tempStrings = temp.Split '|'
    
        let restoredValues =
            [ for i = 0 to tempStrings.Length - 1 do
                  Double.Parse tempStrings[i] ]
    
        for i = 0 to values.Length - 1 do
            printfn $"""{values[i]} {if values[ i ].Equals restoredValues[i] then "=" else "<>"} {restoredValues[i]}""")
    
    // The example displays the following output:
    //       2.17821782178218 <> 2.17821782178218
    //       0.333333333333333 <> 0.333333333333333
    //       3.14159265358979 <> 3.14159265358979
    
    Imports System.IO
    
    Module Example
       Public Sub Main()
          Dim sw As New StreamWriter(".\Doubles.dat")
          Dim values() As Double = { 2.2/1.01, 1.0/3, 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 Double
          Dim sr As New StreamReader(".\Doubles.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) = Double.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.17821782178218 <> 2.17821782178218
    '       0.333333333333333 <> 0.333333333333333
    '       3.14159265358979 <> 3.14159265358979
    

    W takim przypadku wartości można pomyślnie zaokrąglić przy użyciu standardowego ciągu formatu liczbowego "G17", aby zachować pełną precyzję Double wartości, jak pokazano w poniższym przykładzie.

    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:G17}{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
    
    open System
    open System.IO
    
    let values = [ 2.2 / 1.01; 1. / 3.; Math.PI ]
    
    using (new StreamWriter(@".\Doubles.dat")) (fun sw -> 
        for i = 0 to values.Length - 1 do
            sw.Write $"""{values[i]:G17}{if i < values.Length - 1 then "|" else ""}""")
    
    using (new StreamReader(@".\Doubles.dat")) (fun sr ->
        let temp = sr.ReadToEnd()
        let tempStrings = temp.Split '|'
        
        let restoredValues = 
          [ for i = 0 to tempStrings.Length - 1 do
                Double.Parse tempStrings[i] ]
    
        for i = 0 to values.Length - 1 do
            printfn $"""{restoredValues[i]} {if values[i].Equals restoredValues[i] then "=" else "<>"} {values[i]}""")
    
    // The example displays the following output:
    //       2.17821782178218 = 2.17821782178218
    //       0.333333333333333 = 0.333333333333333
    //       3.14159265358979 = 3.14159265358979
    
    Imports System.IO
    
    Module Example
       Public Sub Main()
          Dim sw As New StreamWriter(".\Doubles.dat")
          Dim values() As Double = { 2.2/1.01, 1.0/3, Math.PI }
          For ctr As Integer = 0 To values.Length - 1
             sw.Write("{0:G17}{1}", values(ctr), 
                      If(ctr < values.Length - 1, "|", ""))
          Next      
          sw.Close()
          
          Dim restoredValues(values.Length - 1) As Double
          Dim sr As New StreamReader(".\Doubles.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) = Double.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.17821782178218 = 2.17821782178218
    '       0.333333333333333 = 0.333333333333333
    '       3.14159265358979 = 3.14159265358979
    

Ważne

W przypadku użycia z wartością Double specyfikator formatu "R" w niektórych przypadkach nie może pomyślnie zaokrąglić oryginalnej wartości. Aby upewnić się, że Double wartości zostały pomyślnie zaokrąglone, użyj specyfikatora formatu "G17".

  • Single wartości mają mniejszą precyzję niż Double wartości. Single Wartość konwertowana na pozornie równoważną Double często nie jest równa Double wartości ze względu na różnice w precyzji. W poniższym przykładzie wynik identycznych operacji dzielenia jest przypisywany do Double wartości i Single . Single Po rzutaniu wartości na Doublewartość , porównanie dwóch wartości pokazuje, że są one nierówne.

    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
    
    open System
    
    let value1 = 1. / 3.
    let sValue2 = 1f /3f
    
    let value2 = double sValue2
    printfn $"{value1:R} = {value2:R}: {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
    

    Aby uniknąć tego problemu, użyj metody zamiast Single typu danych lub użyj Double Round metody , aby obie wartości miały taką samą precyzję.

Ponadto wynik operacji arytmetycznych i przypisań z wartościami Double może się nieznacznie różnić w zależności od platformy ze względu na utratę dokładności Double typu. Na przykład wynik przypisywania wartości literału Double może się różnić w 32-bitowych i 64-bitowych wersjach .NET Framework. Poniższy przykład ilustruje tę różnicę, gdy wartość literału -4.42330604244772E-305 i zmienna, której wartość to -4.4233060424772E-305 są przypisywane do zmiennej Double . Należy pamiętać, że wynik Parse(String) metody w tym przypadku nie cierpi na utratę precyzji.

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
let value = -4.42330604244772E-305

let fromLiteral = -4.42330604244772E-305
let fromVariable = value
let fromParse = Double.Parse "-4.42330604244772E-305"

printfn $"Double value from literal: {fromLiteral,29:R}"
printfn $"Double value from variable: {fromVariable,28:R}"
printfn $"Double value from Parse method: {fromParse,24:R}"
// 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
Dim value As Double = -4.42330604244772E-305

Dim fromLiteral As Double = -4.42330604244772E-305
Dim fromVariable As Double = value
Dim fromParse As Double = 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

Testowanie pod kątem równości

Aby uznać za równe, dwie Double wartości muszą reprezentować identyczne wartości. Jednak ze względu na różnice w dokładności między wartościami lub z powodu utraty dokładności o jedną lub obie wartości wartości zmiennoprzecinkowe, które powinny być identyczne, często okazuje się nierówne ze względu na różnice w ich najmniej znaczących cyfrach. W rezultacie wywołania Equals metody w celu określenia, czy dwie wartości są równe, czy wywołania CompareTo metody w celu określenia relacji między dwiema Double wartościami, często dają nieoczekiwane wyniki. Jest to widoczne w poniższym przykładzie, gdzie dwie najwyraźniej równe Double wartości okazują się nierówne, ponieważ pierwszy ma 15 cyfr dokładności, podczas gdy drugi ma 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
open System

let value1 = 0.333333333333333
let value2 = 1. / 3.
printfn $"{value1:R} = {value2:R}: {value1.Equals value2}"
// The example displays the following output:
//        0.333333333333333 = 0.33333333333333331: False
Module Example
   Public Sub Main()
      Dim value1 As Double = .333333333333333
      Dim value2 As Double = 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.333333333333333 = 0.33333333333333331: False

Obliczone wartości, które są zgodne z różnymi ścieżkami kodu i które są manipulowane na różne sposoby, często okazują się nierówne. W poniższym przykładzie jedna Double wartość jest kwadratowa, a następnie pierwiastek kwadratowy jest obliczany w celu przywrócenia oryginalnej wartości. Druga Double wartość jest mnożona przez 3,51 i kwadratowa, zanim pierwiastek kwadratowy wyniku jest podzielony przez 3,51, aby przywrócić oryginalną wartość. Chociaż dwie wartości wydają się być identyczne, wywołanie Equals(Double) metody wskazuje, że nie są równe. Używając standardowego ciągu formatu "R", aby zwrócić ciąg wynikowy, który wyświetla wszystkie znaczące cyfry każdej wartości podwójnej, pokazuje, że druga wartość to .0000000000001 mniejsza niż pierwsza.

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
open System

let value1 = 
    Math.Pow(100.10142, 2)
    |> sqrt

let value2 = 
    let v = pown (value1 * 3.51) 2
    (Math.Sqrt v) / 3.51

printfn $"{value1} = {value2}: {value1.Equals value2}\n"
printfn $"{value1:R} = {value2:R}"
// The example displays the following output:
//    100.10142 = 100.10142: False
//
//    100.10142 = 100.10141999999999
Module Example
   Public Sub Main()
      Dim value1 As Double = 100.10142
      value1 = Math.Sqrt(Math.Pow(value1, 2))
      Dim value2 As Double = Math.Pow(value1 * 3.51, 2)
      value2 = Math.Sqrt(value2) / 3.51
      Console.WriteLine("{0} = {1}: {2}", 
                        value1, value2, value1.Equals(value2)) 
      Console.WriteLine()
      Console.WriteLine("{0:R} = {1:R}", value1, value2) 
   End Sub
End Module
' The example displays the following output:
'    100.10142 = 100.10142: False
'    
'    100.10142 = 100.10141999999999

W przypadkach, gdy utrata precyzji może mieć wpływ na wynik porównania, można zastosować dowolną z następujących alternatyw do wywołania Equals metody lub CompareTo :

  • Wywołaj metodę, Math.Round aby upewnić się, że obie wartości mają taką samą precyzję. Poniższy przykład modyfikuje poprzedni przykład, aby użyć tego podejścia, tak aby dwie wartości ułamkowe były równoważne.

    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
    
    open System
    
    let v1 = 0.333333333333333
    let v2 = 1. / 3.
    let precision = 7
    let value1 = Math.Round(v1, precision)
    let value2 = Math.Round(v2, precision)
    printfn $"{value1:R} = {value2:R}: {value1.Equals value2}"
    // The example displays the following output:
    //        0.3333333 = 0.3333333: True
    
    Module Example
       Public Sub Main()
          Dim value1 As Double = .333333333333333
          Dim value2 As Double = 1/3
          Dim precision As Integer = 7
          value1 = Math.Round(value1, precision)
          value2 = 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
    

    Problem dokładności nadal dotyczy zaokrąglania wartości punktu środkowego. Aby uzyskać więcej informacji, zobacz metodę Math.Round(Double, Int32, MidpointRounding) .

  • Przetestuj przybliżoną równość, a nie równość. Wymaga to zdefiniowania wartości bezwzględnej, o którą dwie wartości mogą się różnić, ale nadal są równe, lub że definiujesz względną kwotę, za pomocą której mniejsza wartość może odbiegać od większej wartości.

    Ostrzeżenie

    Double.Epsilon jest czasami używana jako bezwzględna miara odległości między dwiema Double wartościami podczas testowania równości. Jednak Double.Epsilon mierzy najmniejszą możliwą wartość, którą można dodać do lub odejmować od, Double której wartość to zero. W przypadku większości wartości dodatnich i ujemnych Double wartość Double.Epsilon jest za mała, aby zostać wykryta. Dlatego z wyjątkiem wartości, które są zerowe, nie zalecamy używania jej w testach równości.

    W poniższym przykładzie użyto drugiego podejścia do zdefiniowania IsApproximatelyEqual metody, która sprawdza względną różnicę między dwiema wartościami. Kontrastuje również wynik wywołań metody IsApproximatelyEqual i Equals(Double) metody.

    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
    
    open System
    
    let isApproximatelyEqual (value1: double) (value2: double) (epsilon: double) =
        // If they are equal anyway, just return True.
        if value1.Equals value2 then 
            true
        else
            // Handle NaN, Infinity.
            if Double.IsInfinity value1 || Double.IsNaN value1 then 
                value1.Equals value2
            elif Double.IsInfinity value2 || Double.IsNaN value2 then
                value1.Equals value2
            else
                // Handle zero to avoid division by zero
                let divisor = max value1 value2
                let divisor = 
                    if divisor.Equals 0 then
                        min value1 value2
                    else 
                        divisor
                abs ((value1 - value2) / divisor) <= epsilon
    
    let one1 = 0.1 * 10.
    let mutable one2 = 0.
    for _ = 1 to 10 do
        one2 <- one2 + 0.1
    
    printfn $"{one1:R} = {one2:R}: {one1.Equals one2}"
    printfn $"{one1:R} is approximately equal to {one2:R}: {isApproximatelyEqual one1 one2 0.000000001}"
    
    // The example displays the following output:
    //       1 = 0.99999999999999989: False
    //       1 is approximately equal to 0.99999999999999989: True
    
    Module Example
       Public Sub Main()
          Dim one1 As Double = .1 * 10
          Dim one2 As Double = 0
          For ctr As Integer = 1 To 10
             one2 += .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, .000000001))   
       End Sub
    
       Function IsApproximatelyEqual(value1 As Double, value2 As Double, 
                                     epsilon As Double) As Boolean
          ' If they are equal anyway, just return True.
          If value1.Equals(value2) Then Return True
          
          ' Handle NaN, Infinity.
          If Double.IsInfinity(value1) Or Double.IsNaN(value1) Then
             Return value1.Equals(value2)
          Else If Double.IsInfinity(value2) Or Double.IsNaN(value2)
             Return value1.Equals(value2)
          End If
          
          ' Handle zero to avoid division by zero
          Dim divisor As Double = 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 = 0.99999999999999989: False
    '       1 is approximately equal to 0.99999999999999989: True
    

Wartości zmiennoprzecinkowe i wyjątki

W przeciwieństwie do operacji z typami całkowitymi, które zgłaszają wyjątki w przypadkach przepełnienia lub nielegalnych operacji, takich jak podział o zero, operacje z wartościami zmiennoprzecinkowymi nie zgłaszają wyjątków. Zamiast tego w wyjątkowych sytuacjach wynik operacji zmiennoprzecinkowych wynosi zero, nieskończoność dodatnia, nieskończoność ujemna lub nie liczba (NaN):

  • Jeśli wynik operacji zmiennoprzecinkowych jest za mały dla formatu docelowego, wynik jest zerowy. Może się to zdarzyć, gdy zostaną pomnożone dwie bardzo małe liczby, jak pokazano w poniższym przykładzie.

    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
    
    let value1 = 1.1632875981534209e-225
    let value2 = 9.1642346778e-175
    let result = value1 * value2
    printfn $"{value1} * {value2} = {result}"
    printfn $"{result} = 0: {result.Equals 0.0}"
    // The example displays the following output:
    //       1.16328759815342E-225 * 9.1642346778E-175 = 0
    //       0 = 0: True
    
    Module Example
       Public Sub Main()
          Dim value1 As Double = 1.1632875981534209e-225
          Dim value2 As Double = 9.1642346778e-175
          Dim result As Double = value1 * value2
          Console.WriteLine("{0} * {1} = {2}", value1, value2, result)
          Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0))
       End Sub
    End Module
    ' The example displays the following output:
    '       1.16328759815342E-225 * 9.1642346778E-175 = 0
    '       0 = 0: True
    
  • Jeśli wielkość wyniku operacji zmiennoprzecinkowa przekracza zakres formatu docelowego, wynik operacji to PositiveInfinity lub NegativeInfinity, odpowiednio dla znaku wyniku. Wynikiem operacji, która przepełnia Double.MaxValue się, jest PositiveInfinity, a wynikiem operacji, która przepełnia Double.MinValue się, jest NegativeInfinity, jak pokazano w poniższym przykładzie.

    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
    
    open System
    
    let value1 = 4.565e153
    let value2 = 6.9375e172
    let result = value1 * value2
    printfn $"PositiveInfinity: {Double.IsPositiveInfinity result}"
    printfn $"NegativeInfinity: {Double.IsNegativeInfinity result}\n"
    
    let value3 = - value1
    let result2 = value2 * value3
    printfn $"PositiveInfinity: {Double.IsPositiveInfinity result2}"
    printfn $"NegativeInfinity: {Double.IsNegativeInfinity result2}"
    
    // The example displays the following output:
    //       PositiveInfinity: True
    //       NegativeInfinity: False
    //
    //       PositiveInfinity: False
    //       NegativeInfinity: True
    
    Module Example
       Public Sub Main()
          Dim value1 As Double = 4.565e153
          Dim value2 As Double = 6.9375e172
          Dim result As Double = value1 * value2
          Console.WriteLine("PositiveInfinity: {0}", 
                             Double.IsPositiveInfinity(result))
          Console.WriteLine("NegativeInfinity: {0}", 
                            Double.IsNegativeInfinity(result))
          Console.WriteLine()                  
          value1 = -value1
          result = value1 * value2
          Console.WriteLine("PositiveInfinity: {0}", 
                             Double.IsPositiveInfinity(result))
          Console.WriteLine("NegativeInfinity: {0}", 
                            Double.IsNegativeInfinity(result))
       End Sub
    End Module
    ' The example displays the following output:
    '       PositiveInfinity: True
    '       NegativeInfinity: False
    '       
    '       PositiveInfinity: False
    '       NegativeInfinity: True
    

    PositiveInfinity wynika również z podziału o zero z dodatnią dywidendą i NegativeInfinity wynika z podziału o zero z ujemną dywidendą.

  • Jeśli operacja zmiennoprzecinkowa jest nieprawidłowa, wynikiem operacji jest NaN. Na przykład NaN wyniki z następujących operacji:

  • Dowolna operacja zmiennoprzecinkowa z nieprawidłowym wejściem. Na przykład wywołanie metody z wartością ujemną zwraca NaNwartość , podobnie jak wywołanie Math.Sqrt Math.Acos metody z wartością większą niż jedna lub mniejsza niż ujemna.

  • Dowolna operacja z argumentem, którego wartość to Double.NaN.

Konwersje typów i struktura Podwójna

Struktura Double nie definiuje żadnych jawnych ani niejawnych operatorów konwersji. Zamiast tego konwersje są implementowane przez kompilator.

Konwersja wartości dowolnego typu liczbowego pierwotnego na Double wartość jest konwersją rozszerzającą i dlatego nie wymaga jawnego operatora rzutowania ani wywołania metody konwersji, chyba że kompilator jawnie go wymaga. Na przykład kompilator języka C# wymaga operatora rzutowania konwersji z Decimal na Double, podczas gdy kompilator Visual Basic nie. Poniższy przykład konwertuje minimalną lub maksymalną wartość innych pierwotnych typów liczbowych na wartość Double.

using System;

public class Example
{
   public static void Main()
   {
      dynamic[] values = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
                           Decimal.MaxValue, Int16.MinValue, Int16.MaxValue,
                           Int32.MinValue, Int32.MaxValue, Int64.MinValue,
                           Int64.MaxValue, SByte.MinValue, SByte.MaxValue,
                           Single.MinValue, Single.MaxValue, UInt16.MinValue,
                           UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
                           UInt64.MinValue, UInt64.MaxValue };
      double dblValue;
      foreach (var value in values) {
         if (value.GetType() == typeof(Decimal))
            dblValue = (Double) value;
         else
            dblValue = value;
         Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
                           value, value.GetType().Name,
                           dblValue, dblValue.GetType().Name);
      }
   }
}
// The example displays the following output:
//    0 (Byte) --> 0 (Double)
//    255 (Byte) --> 255 (Double)
//    -79228162514264337593543950335 (Decimal) --> -7.9228162514264338E+28 (Double)
//    79228162514264337593543950335 (Decimal) --> 7.9228162514264338E+28 (Double)
//    -32768 (Int16) --> -32768 (Double)
//    32767 (Int16) --> 32767 (Double)
//    -2147483648 (Int32) --> -2147483648 (Double)
//    2147483647 (Int32) --> 2147483647 (Double)
//    -9223372036854775808 (Int64) --> -9.2233720368547758E+18 (Double)
//    9223372036854775807 (Int64) --> 9.2233720368547758E+18 (Double)
//    -128 (SByte) --> -128 (Double)
//    127 (SByte) --> 127 (Double)
//    -3.402823E+38 (Single) --> -3.4028234663852886E+38 (Double)
//    3.402823E+38 (Single) --> 3.4028234663852886E+38 (Double)
//    0 (UInt16) --> 0 (Double)
//    65535 (UInt16) --> 65535 (Double)
//    0 (UInt32) --> 0 (Double)
//    4294967295 (UInt32) --> 4294967295 (Double)
//    0 (UInt64) --> 0 (Double)
//    18446744073709551615 (UInt64) --> 1.8446744073709552E+19 (Double)
open System

let values: obj[] = 
    [| Byte.MinValue; Byte.MaxValue; Decimal.MinValue
       Decimal.MaxValue; Int16.MinValue; Int16.MaxValue
       Int32.MinValue; Int32.MaxValue; Int64.MinValue
       Int64.MaxValue; SByte.MinValue; SByte.MaxValue
       Single.MinValue; Single.MaxValue; UInt16.MinValue
       UInt16.MaxValue; UInt32.MinValue, UInt32.MaxValue
       UInt64.MinValue; UInt64.MaxValue |]

for value in values do
    let dblValue = value :?> double
    printfn $"{value} ({value.GetType().Name}) --> {dblValue:R} ({dblValue.GetType().Name})"
// The example displays the following output:
//    0 (Byte) --> 0 (Double)
//    255 (Byte) --> 255 (Double)
//    -79228162514264337593543950335 (Decimal) --> -7.9228162514264338E+28 (Double)
//    79228162514264337593543950335 (Decimal) --> 7.9228162514264338E+28 (Double)
//    -32768 (Int16) --> -32768 (Double)
//    32767 (Int16) --> 32767 (Double)
//    -2147483648 (Int32) --> -2147483648 (Double)
//    2147483647 (Int32) --> 2147483647 (Double)
//    -9223372036854775808 (Int64) --> -9.2233720368547758E+18 (Double)
//    9223372036854775807 (Int64) --> 9.2233720368547758E+18 (Double)
//    -128 (SByte) --> -128 (Double)
//    127 (SByte) --> 127 (Double)
//    -3.402823E+38 (Single) --> -3.4028234663852886E+38 (Double)
//    3.402823E+38 (Single) --> 3.4028234663852886E+38 (Double)
//    0 (UInt16) --> 0 (Double)
//    65535 (UInt16) --> 65535 (Double)
//    0 (UInt32) --> 0 (Double)
//    4294967295 (UInt32) --> 4294967295 (Double)
//    0 (UInt64) --> 0 (Double)
//    18446744073709551615 (UInt64) --> 1.8446744073709552E+19 (Double)
Module Example
   Public Sub Main()
      Dim values() As Object = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
                                 Decimal.MaxValue, Int16.MinValue, Int16.MaxValue,
                                 Int32.MinValue, Int32.MaxValue, Int64.MinValue,
                                 Int64.MaxValue, SByte.MinValue, SByte.MaxValue,
                                 Single.MinValue, Single.MaxValue, UInt16.MinValue,
                                 UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
                                 UInt64.MinValue, UInt64.MaxValue }
      Dim dblValue As Double
      For Each value In values
         dblValue = value
         Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
                           value, value.GetType().Name,
                           dblValue, dblValue.GetType().Name)
      Next
   End Sub
End Module
' The example displays the following output:
'    0 (Byte) --> 0 (Double)
'    255 (Byte) --> 255 (Double)
'    -79228162514264337593543950335 (Decimal) --> -7.9228162514264338E+28 (Double)
'    79228162514264337593543950335 (Decimal) --> 7.9228162514264338E+28 (Double)
'    -32768 (Int16) --> -32768 (Double)
'    32767 (Int16) --> 32767 (Double)
'    -2147483648 (Int32) --> -2147483648 (Double)
'    2147483647 (Int32) --> 2147483647 (Double)
'    -9223372036854775808 (Int64) --> -9.2233720368547758E+18 (Double)
'    9223372036854775807 (Int64) --> 9.2233720368547758E+18 (Double)
'    -128 (SByte) --> -128 (Double)
'    127 (SByte) --> 127 (Double)
'    -3.402823E+38 (Single) --> -3.4028234663852886E+38 (Double)
'    3.402823E+38 (Single) --> 3.4028234663852886E+38 (Double)
'    0 (UInt16) --> 0 (Double)
'    65535 (UInt16) --> 65535 (Double)
'    0 (UInt32) --> 0 (Double)
'    4294967295 (UInt32) --> 4294967295 (Double)
'    0 (UInt64) --> 0 (Double)
'    18446744073709551615 (UInt64) --> 1.8446744073709552E+19 (Double)

Ponadto Single wartości Single.NaN, Single.PositiveInfinityi Single.NegativeInfinity konwertują odpowiednio na Double.NaN, Double.PositiveInfinityi Double.NegativeInfinity.

Należy pamiętać, że konwersja wartości niektórych typów liczbowych na Double wartość może obejmować utratę dokładności. Jak pokazano w przykładzie, utrata dokładności jest możliwa podczas konwertowania Decimalwartości , Int64i UInt64 na Double wartości.

Konwersja Double wartości na wartość dowolnego innego pierwotnego typu danych liczbowych jest konwersją zawężającą i wymaga operatora rzutowania (w języku C#), metody konwersji (w Visual Basic) lub wywołania Convert metody. Wartości, które znajdują się poza zakresem docelowego typu danych, które są zdefiniowane przez typ docelowy MinValue i MaxValue właściwości, zachowują się tak, jak pokazano w poniższej tabeli.

Typ docelowy Wynik
Dowolny typ całkowity Wyjątek OverflowException , jeśli konwersja występuje w zaznaczonym kontekście.

Jeśli konwersja występuje w nieznakowanym kontekście (wartość domyślna w języku C#), operacja konwersji zakończy się pomyślnie, ale wartość przepełnia się.
Decimal Wyjątek OverflowException .
Single Single.NegativeInfinity dla wartości ujemnych.

Single.PositiveInfinity dla wartości dodatnich.

Ponadto , Double.NaNDouble.PositiveInfinityi Double.NegativeInfinity zgłaszają OverflowException konwersje na liczby całkowite w zaznaczonym kontekście, ale te wartości przepełniają się po przekonwertowaniu na liczby całkowite w nieznakowanym kontekście. W przypadku konwersji na Decimalelement zawsze zgłaszają element OverflowException. W przypadku konwersji na Single, są konwertowane odpowiednio na Single.NaN, Single.PositiveInfinityi Single.NegativeInfinity.

Należy pamiętać, że utrata dokładności może wynikać z konwertowania Double wartości na inny typ liczbowy. W przypadku konwersji na dowolne typy całkowite, ponieważ dane wyjściowe z przykładu pokazują, składnik ułamkowy zostanie utracony, gdy Double wartość jest zaokrąglona (jak w Visual Basic) lub obcięta (jak w języku C#). W przypadku konwersji na Decimal wartości Double i Single wartość może nie mieć dokładnej reprezentacji w docelowym typie danych.

Poniższy przykład konwertuje liczbę Double wartości na kilka innych typów liczbowych. Konwersje występują w zaznaczonym kontekście w Visual Basic (wartość domyślna), w języku C# (ze względu na zaznaczone słowo kluczowe) i w języku F# (ze względu na moduł Sprawdzony). Dane wyjściowe z przykładu pokazują wynik konwersji w obu zaznaczonych kontekstach. Konwersje można wykonać w nieznakowanym kontekście w Visual Basic, kompilując z przełącznikiem kompilatora/removeintchecks+, w języku C#, komentując instrukcję i w języku F#, komentując checked instrukcjęopen Checked.

using System;

public class Example
{
   public static void Main()
   {
      Double[] values = { Double.MinValue, -67890.1234, -12345.6789,
                          12345.6789, 67890.1234, Double.MaxValue,
                          Double.NaN, Double.PositiveInfinity,
                          Double.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);
            }
            try {
                Single sValue = (float) value;
                Console.WriteLine("{0} ({1}) --> {2} ({3})",
                                  value, value.GetType().Name,
                                  sValue, sValue.GetType().Name);
            }
            catch (OverflowException) {
               Console.WriteLine("Unable to convert {0} to Single.", value);
            }
            Console.WriteLine();
         }
      }
   }
}
// The example displays the following output for conversions performed
// in a checked context:
//       Unable to convert -1.79769313486232E+308 to Int64.
//       Unable to convert -1.79769313486232E+308 to UInt64.
//       Unable to convert -1.79769313486232E+308 to Decimal.
//       -1.79769313486232E+308 (Double) --> -Infinity (Single)
//
//       -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       Unable to convert -67890.1234 to UInt64.
//       -67890.1234 (Double) --> -67890.1234 (Decimal)
//       -67890.1234 (Double) --> -67890.13 (Single)
//
//       -12345.6789 (Double) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       Unable to convert -12345.6789 to UInt64.
//       -12345.6789 (Double) --> -12345.6789 (Decimal)
//       -12345.6789 (Double) --> -12345.68 (Single)
//
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (Int64)
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (UInt64)
//       12345.6789 (Double) --> 12345.6789 (Decimal)
//       12345.6789 (Double) --> 12345.68 (Single)
//
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64)
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64)
//       67890.1234 (Double) --> 67890.1234 (Decimal)
//       67890.1234 (Double) --> 67890.13 (Single)
//
//       Unable to convert 1.79769313486232E+308 to Int64.
//       Unable to convert 1.79769313486232E+308 to UInt64.
//       Unable to convert 1.79769313486232E+308 to Decimal.
//       1.79769313486232E+308 (Double) --> Infinity (Single)
//
//       Unable to convert NaN to Int64.
//       Unable to convert NaN to UInt64.
//       Unable to convert NaN to Decimal.
//       NaN (Double) --> NaN (Single)
//
//       Unable to convert Infinity to Int64.
//       Unable to convert Infinity to UInt64.
//       Unable to convert Infinity to Decimal.
//       Infinity (Double) --> Infinity (Single)
//
//       Unable to convert -Infinity to Int64.
//       Unable to convert -Infinity to UInt64.
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Double) --> -Infinity (Single)
// The example displays the following output for conversions performed
// in an unchecked context:
//       -1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -1.79769313486232E+308 (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -1.79769313486232E+308 to Decimal.
//       -1.79769313486232E+308 (Double) --> -Infinity (Single)
//
//       -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       -67890.1234 (Double) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
//       -67890.1234 (Double) --> -67890.1234 (Decimal)
//       -67890.1234 (Double) --> -67890.13 (Single)
//
//       -12345.6789 (Double) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       -12345.6789 (Double) --> 18446744073709539271 (0xFFFFFFFFFFFFCFC7) (UInt64)
//       -12345.6789 (Double) --> -12345.6789 (Decimal)
//       -12345.6789 (Double) --> -12345.68 (Single)
//
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (Int64)
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (UInt64)
//       12345.6789 (Double) --> 12345.6789 (Decimal)
//       12345.6789 (Double) --> 12345.68 (Single)
//
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64)
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64)
//       67890.1234 (Double) --> 67890.1234 (Decimal)
//       67890.1234 (Double) --> 67890.13 (Single)
//
//       1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       1.79769313486232E+308 (Double) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert 1.79769313486232E+308 to Decimal.
//       1.79769313486232E+308 (Double) --> Infinity (Single)
//
//       NaN (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       NaN (Double) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert NaN to Decimal.
//       NaN (Double) --> NaN (Single)
//
//       Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       Infinity (Double) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert Infinity to Decimal.
//       Infinity (Double) --> Infinity (Single)
//
//       -Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -Infinity (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Double) --> -Infinity (Single)
open System
open Checked

let values = 
    [| Double.MinValue; -67890.1234; -12345.6789
       12345.6789; 67890.1234; Double.MaxValue
       Double.NaN; Double.PositiveInfinity;
       Double.NegativeInfinity |]

for value in values do
    try
        let lValue = int64 value
        printfn $"{value} ({value.GetType().Name}) --> {lValue} (0x{lValue:X16}) ({lValue.GetType().Name})"
    with :? OverflowException ->
        printfn $"Unable to convert {value} to Int64."
    try
        let ulValue = uint64 value
        printfn $"{value} ({value.GetType().Name}) --> {ulValue} (0x{ulValue:X16}) ({ulValue.GetType().Name})"
    with :? OverflowException ->
        printfn $"Unable to convert {value} to UInt64."
    try
        let dValue = decimal value
        printfn $"{value} ({value.GetType().Name}) --> {dValue} ({dValue.GetType().Name})"
    with :? OverflowException ->
        printfn $"Unable to convert {value} to Decimal."
    try
        let sValue = float32 value
        printfn $"{value} ({value.GetType().Name}) --> {sValue} ({sValue.GetType().Name})"
    with :? OverflowException ->
        printfn $"Unable to convert {value} to Single."
    printfn ""
// The example displays the following output for conversions performed
// in a checked context:
//       Unable to convert -1.79769313486232E+308 to Int64.
//       Unable to convert -1.79769313486232E+308 to UInt64.
//       Unable to convert -1.79769313486232E+308 to Decimal.
//       -1.79769313486232E+308 (Double) --> -Infinity (Single)
//
//       -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       Unable to convert -67890.1234 to UInt64.
//       -67890.1234 (Double) --> -67890.1234 (Decimal)
//       -67890.1234 (Double) --> -67890.13 (Single)
//
//       -12345.6789 (Double) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       Unable to convert -12345.6789 to UInt64.
//       -12345.6789 (Double) --> -12345.6789 (Decimal)
//       -12345.6789 (Double) --> -12345.68 (Single)
//
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (Int64)
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (UInt64)
//       12345.6789 (Double) --> 12345.6789 (Decimal)
//       12345.6789 (Double) --> 12345.68 (Single)
//
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64)
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64)
//       67890.1234 (Double) --> 67890.1234 (Decimal)
//       67890.1234 (Double) --> 67890.13 (Single)
//
//       Unable to convert 1.79769313486232E+308 to Int64.
//       Unable to convert 1.79769313486232E+308 to UInt64.
//       Unable to convert 1.79769313486232E+308 to Decimal.
//       1.79769313486232E+308 (Double) --> Infinity (Single)
//
//       Unable to convert NaN to Int64.
//       Unable to convert NaN to UInt64.
//       Unable to convert NaN to Decimal.
//       NaN (Double) --> NaN (Single)
//
//       Unable to convert Infinity to Int64.
//       Unable to convert Infinity to UInt64.
//       Unable to convert Infinity to Decimal.
//       Infinity (Double) --> Infinity (Single)
//
//       Unable to convert -Infinity to Int64.
//       Unable to convert -Infinity to UInt64.
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Double) --> -Infinity (Single)
// The example displays the following output for conversions performed
// in an unchecked context:
//       -1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -1.79769313486232E+308 (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -1.79769313486232E+308 to Decimal.
//       -1.79769313486232E+308 (Double) --> -Infinity (Single)
//
//       -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       -67890.1234 (Double) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
//       -67890.1234 (Double) --> -67890.1234 (Decimal)
//       -67890.1234 (Double) --> -67890.13 (Single)
//
//       -12345.6789 (Double) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       -12345.6789 (Double) --> 18446744073709539271 (0xFFFFFFFFFFFFCFC7) (UInt64)
//       -12345.6789 (Double) --> -12345.6789 (Decimal)
//       -12345.6789 (Double) --> -12345.68 (Single)
//
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (Int64)
//       12345.6789 (Double) --> 12345 (0x0000000000003039) (UInt64)
//       12345.6789 (Double) --> 12345.6789 (Decimal)
//       12345.6789 (Double) --> 12345.68 (Single)
//
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64)
//       67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64)
//       67890.1234 (Double) --> 67890.1234 (Decimal)
//       67890.1234 (Double) --> 67890.13 (Single)
//
//       1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       1.79769313486232E+308 (Double) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert 1.79769313486232E+308 to Decimal.
//       1.79769313486232E+308 (Double) --> Infinity (Single)
//
//       NaN (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       NaN (Double) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert NaN to Decimal.
//       NaN (Double) --> NaN (Single)
//
//       Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       Infinity (Double) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert Infinity to Decimal.
//       Infinity (Double) --> Infinity (Single)
//
//       -Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -Infinity (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Double) --> -Infinity (Single)
Module Example
   Public Sub Main()
      Dim values() As Double = { Double.MinValue, -67890.1234, -12345.6789,
                                 12345.6789, 67890.1234, Double.MaxValue,
                                 Double.NaN, Double.PositiveInfinity,
                                 Double.NegativeInfinity }
      For Each value In values
         Try
             Dim lValue As Int64 = 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
         Try
             Dim sValue As Single = CSng(value)
             Console.WriteLine("{0} ({1}) --> {2} ({3})",
                               value, value.GetType().Name,
                               sValue, sValue.GetType().Name)
         Catch e As OverflowException
            Console.WriteLine("Unable to convert {0} to Single.", value)
         End Try
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output for conversions performed
' in a checked context:
'       Unable to convert -1.79769313486232E+308 to Int64.
'       Unable to convert -1.79769313486232E+308 to UInt64.
'       Unable to convert -1.79769313486232E+308 to Decimal.
'       -1.79769313486232E+308 (Double) --> -Infinity (Single)
'
'       -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
'       Unable to convert -67890.1234 to UInt64.
'       -67890.1234 (Double) --> -67890.1234 (Decimal)
'       -67890.1234 (Double) --> -67890.13 (Single)
'
'       -12345.6789 (Double) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64)
'       Unable to convert -12345.6789 to UInt64.
'       -12345.6789 (Double) --> -12345.6789 (Decimal)
'       -12345.6789 (Double) --> -12345.68 (Single)
'
'       12345.6789 (Double) --> 12346 (0x000000000000303A) (Int64)
'       12345.6789 (Double) --> 12346 (0x000000000000303A) (UInt64)
'       12345.6789 (Double) --> 12345.6789 (Decimal)
'       12345.6789 (Double) --> 12345.68 (Single)
'
'       67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64)
'       67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64)
'       67890.1234 (Double) --> 67890.1234 (Decimal)
'       67890.1234 (Double) --> 67890.13 (Single)
'
'       Unable to convert 1.79769313486232E+308 to Int64.
'       Unable to convert 1.79769313486232E+308 to UInt64.
'       Unable to convert 1.79769313486232E+308 to Decimal.
'       1.79769313486232E+308 (Double) --> Infinity (Single)
'
'       Unable to convert NaN to Int64.
'       Unable to convert NaN to UInt64.
'       Unable to convert NaN to Decimal.
'       NaN (Double) --> NaN (Single)
'
'       Unable to convert Infinity to Int64.
'       Unable to convert Infinity to UInt64.
'       Unable to convert Infinity to Decimal.
'       Infinity (Double) --> Infinity (Single)
'
'       Unable to convert -Infinity to Int64.
'       Unable to convert -Infinity to UInt64.
'       Unable to convert -Infinity to Decimal.
'       -Infinity (Double) --> -Infinity (Single)
' The example displays the following output for conversions performed
' in an unchecked context:
'       -1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       -1.79769313486232E+308 (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64)
'       Unable to convert -1.79769313486232E+308 to Decimal.
'       -1.79769313486232E+308 (Double) --> -Infinity (Single)
'
'       -67890.1234 (Double) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
'       -67890.1234 (Double) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
'       -67890.1234 (Double) --> -67890.1234 (Decimal)
'       -67890.1234 (Double) --> -67890.13 (Single)
'
'       -12345.6789 (Double) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64)
'       -12345.6789 (Double) --> 18446744073709539270 (0xFFFFFFFFFFFFCFC6) (UInt64)
'       -12345.6789 (Double) --> -12345.6789 (Decimal)
'       -12345.6789 (Double) --> -12345.68 (Single)
'
'       12345.6789 (Double) --> 12346 (0x000000000000303A) (Int64)
'       12345.6789 (Double) --> 12346 (0x000000000000303A) (UInt64)
'       12345.6789 (Double) --> 12345.6789 (Decimal)
'       12345.6789 (Double) --> 12345.68 (Single)
'
'       67890.1234 (Double) --> 67890 (0x0000000000010932) (Int64)
'       67890.1234 (Double) --> 67890 (0x0000000000010932) (UInt64)
'       67890.1234 (Double) --> 67890.1234 (Decimal)
'       67890.1234 (Double) --> 67890.13 (Single)
'
'       1.79769313486232E+308 (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       1.79769313486232E+308 (Double) --> 0 (0x0000000000000000) (UInt64)
'       Unable to convert 1.79769313486232E+308 to Decimal.
'       1.79769313486232E+308 (Double) --> Infinity (Single)
'
'       NaN (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       NaN (Double) --> 0 (0x0000000000000000) (UInt64)
'       Unable to convert NaN to Decimal.
'       NaN (Double) --> NaN (Single)
'
'       Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       Infinity (Double) --> 0 (0x0000000000000000) (UInt64)
'       Unable to convert Infinity to Decimal.
'       Infinity (Double) --> Infinity (Single)
'
'       -Infinity (Double) --> -9223372036854775808 (0x8000000000000000) (Int64)
'       -Infinity (Double) --> 9223372036854775808 (0x8000000000000000) (UInt64)
'       Unable to convert -Infinity to Decimal.
'       -Infinity (Double) --> -Infinity (Single)

Aby uzyskać więcej informacji na temat konwersji typów liczbowych, zobacz Konwersja typów w tabelach .NET Framework i konwersji typów.

Funkcje zmiennoprzecinkowe

Struktura Double i powiązane typy udostępniają metody wykonywania operacji w następujących obszarach:

  • Porównanie wartości. Możesz wywołać metodę, Equals aby określić, czy dwie Double wartości są równe, czy CompareTo metoda w celu określenia relacji między dwiema wartościami.

    Struktura Double obsługuje również kompletny zestaw operatorów porównania. Można na przykład przetestować równość lub nierówności albo określić, czy jedna wartość jest większa, czy równa innej. Jeśli jeden z operandów jest typem liczbowym innym niż , Doublejest konwertowany na wartość Double przed wykonaniem porównania.

    Ostrzeżenie

    Ze względu na różnice w precyzji, dwie Double wartości, które powinny być równe, mogą okazać się nierówne, co wpływa na wynik porównania. Aby uzyskać więcej informacji na temat porównywania dwóch Double wartości, zobacz sekcję Testowanie równości.

    Można również wywołać IsNaNmetody , IsInfinity, IsPositiveInfinityi IsNegativeInfinity , aby przetestować te wartości specjalne.

  • Operacje matematyczne. Typowe operacje arytmetyczne, takie jak dodawanie, odejmowanie, mnożenie i dzielenie, są implementowane przez kompilatory języka i instrukcje języka wspólnego (CIL), a nie metody Double . Jeśli jeden z operandów w operacji matematycznej jest typem liczbowym innym niż , Doublejest konwertowany na przed Double wykonaniem operacji. Wynik operacji jest również wartością Double .

    Inne operacje matematyczne mogą być wykonywane przez wywołanie static metod (Sharedw Visual Basic) w System.Math klasie. Obejmuje ona dodatkowe metody powszechnie używane do arytmetyki (na przykład , i ), geometrii (takich jak Math.Absi ) i Math.Sinobliczeń (takich jak Math.LogMath.Cos ).Math.SqrtMath.Sign

    Można również manipulować poszczególnymi bitami w Double wartości. Metoda BitConverter.DoubleToInt64Bits zachowuje Double wzorzec bitowy wartości w 64-bitowej liczbą całkowitą. Metoda BitConverter.GetBytes(Double) zwraca wzorzec bitów w tablicy bajtów.

  • Zaokrąglanie. Zaokrąglanie jest często używane jako technika zmniejszania wpływu różnic między wartościami spowodowanymi problemami z reprezentacją zmiennoprzecinkową i precyzją. Wartość można zaokrąglić Double , wywołując metodę Math.Round .

  • Formatowanie. Możesz przekonwertować wartość na jej reprezentację Double ciągu, wywołując metodę ToString lub używając funkcji formatowania złożonego. Aby uzyskać informacje o sposobie kontrolowania ciągów reprezentujących wartości zmiennoprzecinkowe, zobacz standardowe ciągi formatu liczbowego i niestandardowe ciągi formatu liczbowego .

  • Analizowanie ciągów. Możesz przekonwertować reprezentację ciągu wartości zmiennoprzecinkowej na wartość, wywołując metodę Double Parse lub TryParse . Jeśli operacja analizy zakończy się niepowodzeniem, Parse metoda zgłasza wyjątek, natomiast TryParse metoda zwraca falsewartość .

  • Konwersja typów. Struktura Double zapewnia jawną implementację interfejsu dla interfejsuIConvertible, która obsługuje konwersję między dwoma standardowymi typami danych .NET Framework. Kompilatory języka obsługują również niejawną konwersję wartości wszystkich innych standardowych typów liczbowych na Double wartości. Konwersja wartości dowolnego standardowego typu liczbowego na Double wartość jest konwersją rozszerzającą i nie wymaga od użytkownika operatora rzutowania ani metody konwersji,

    Jednak konwersja Int64 wartości i Single może obejmować utratę dokładności. W poniższej tabeli wymieniono różnice w dokładności dla każdego z tych typów:

    Typ Maksymalna precyzja Precyzja wewnętrzna
    Double 15 17
    Int64 19 cyfr dziesiętnych 19 cyfr dziesiętnych
    Single 7 cyfr dziesiętnych 9 cyfr dziesiętnych

    Problem dokładności najczęściej dotyczy Single wartości konwertowanych na Double wartości. W poniższym przykładzie dwie wartości generowane przez identyczne operacje dzielenia są nierówne, ponieważ jedna z wartości jest wartością zmiennoprzecinkową o pojedynczej precyzji przekonwertowaną na Doublewartość .

    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
    
    let value = 0.1
    let result1 = value * 10.
    let mutable result2 = 0.
    for i = 1 to 10 do
        result2 <- result2 + value
    
    printfn $".1 * 10:           {result1:R}"
    printfn $".1 Added 10 times: {result2:R}"
    // The example displays the following output:
    //       .1 * 10:           1
    //       .1 Added 10 times: 0.99999999999999989
    
    Module Example
       Public Sub Main()
          Dim value As Double = .1
          Dim result1 As Double = value * 10
          Dim result2 As Double
          For ctr As Integer = 1 To 10
             result2 += value
          Next
          Console.WriteLine(".1 * 10:           {0:R}", result1)
          Console.WriteLine(".1 Added 10 times: {0:R}", result2)
       End Sub
    End Module
    ' The example displays the following output:
    '       .1 * 10:           1
    '       .1 Added 10 times: 0.99999999999999989
    

Pola

E

Reprezentuje bazę logarytmicznie naturalną określoną przez stałą e.

Epsilon

Reprezentuje najmniejszą wartość dodatnią Double , która jest większa niż zero. To pole jest stałe.

MaxValue

Reprezentuje największą możliwą wartość elementu Double. To pole jest stałe.

MinValue

Reprezentuje najmniejszą możliwą wartość elementu Double. To pole jest stałe.

NaN

Reprezentuje wartość, która nie jest liczbą (NaN). To pole jest stałe.

NegativeInfinity

Reprezentuje nieskończoność ujemną. To pole jest stałe.

NegativeZero

Reprezentuje liczbę ujemną zero (-0).

Pi

Przedstawia stosunek obwodu okręgu do jego średnicy, określonej przez stałą, π.

PositiveInfinity

Reprezentuje nieskończoność dodatnią. To pole jest stałe.

Tau

Reprezentuje liczbę radianów z jednej kolei określoną przez stałą τ.

Metody

Abs(Double)

Oblicza wartość bezwzględną.

Acos(Double)

Oblicza arc-cosinus wartości.

Acosh(Double)

Oblicza hiperboliczny arc-cosinus wartości.

Asin(Double)

Oblicza sinus arc wartości.

Asinh(Double)

Oblicza sinus arc-sinus hiperboliczny wartości.

Atan(Double)

Oblicza tangens łuku wartości.

Atan2(Double, Double)

Oblicza tangens łukowy ilorazu dwóch wartości.

Atanh(Double)

Oblicza tangens hiperboliczny wartości.

BitDecrement(Double)

Zmniejsza wartość do najmniejszej wartości, która porównuje wartość mniejszą niż dana wartość.

BitIncrement(Double)

Zwiększa wartość do najmniejszej wartości, która porównuje wartość większą niż dana wartość.

Cbrt(Double)

Oblicza element główny modułu wartości.

Ceiling(Double)

Oblicza pułap wartości.

Clamp(Double, Double, Double)

Zaciska wartość do wartości minimalnej i maksymalnej.

CompareTo(Double)

Porównuje to wystąpienie z określoną liczbą zmiennoprzecinkową o podwójnej precyzji i zwraca liczbę całkowitą wskazującą, czy wartość tego wystąpienia jest mniejsza niż, równa lub większa niż wartość określonej liczby zmiennoprzecinkowej o podwójnej precyzji.

CompareTo(Object)

Porównuje to wystąpienie z określonym obiektem i zwraca liczbę całkowitą wskazującą, czy wartość tego wystąpienia jest mniejsza niż, równa lub większa niż wartość określonego obiektu.

CopySign(Double, Double)

Kopiuje znak wartości do znaku innej wartości.

Cos(Double)

Oblicza cosinus wartości.

Cosh(Double)

Oblicza cosinus hiperboliczny wartości.

CreateChecked<TOther>(TOther)

Tworzy wystąpienie bieżącego typu z wartości, zgłaszając wyjątek przepełnienia dla wszystkich wartości, które wykraczają poza reprezentatywny zakres bieżącego typu.

CreateSaturating<TOther>(TOther)

Tworzy wystąpienie bieżącego typu z wartości, saturując wszystkie wartości, które mieszczą się poza reprezentatywnym zakresem bieżącego typu.

CreateTruncating<TOther>(TOther)

Tworzy wystąpienie bieżącego typu z wartości, obcinając wszystkie wartości, które wykraczają poza reprezentatywny zakres bieżącego typu.

Equals(Double)

Zwraca wartość wskazującą, czy to wystąpienie i określony Double obiekt reprezentują tę samą wartość.

Equals(Object)

Zwraca wartość wskazującą, czy to wystąpienie jest równe podanemu obiektowi.

Exp(Double)

Oblicza wartość E podniesioną do danej mocy.

Floor(Double)

Oblicza podłogę wartości.

FusedMultiplyAdd(Double, Double, Double)

Oblicza pomnożone pomnożenie trzech wartości.

GetHashCode()

Zwraca wartość skrótu dla tego wystąpienia.

GetTypeCode()

Zwraca wartość TypeCode dla typu Doublewartości .

Ieee754Remainder(Double, Double)

Oblicza resztę dwóch wartości określonych przez IEEE 754.

ILogB(Double)

Oblicza logarytm liczb całkowitych wartości.

IsFinite(Double)

Określa, czy określona wartość jest skończona (zero, podnormalne lub normalne).

IsInfinity(Double)

Zwraca wartość wskazującą, czy określona liczba ma wartość ujemną lub dodatnią nieskończoność.

IsNaN(Double)

Zwraca wartość wskazującą, czy określona wartość nie jest liczbą (NaN).

IsNegative(Double)

Określa, czy określona wartość jest ujemna.

IsNegativeInfinity(Double)

Zwraca wartość wskazującą, czy określona liczba ma wartość ujemną nieskończoności.

IsNormal(Double)

Określa, czy określona wartość jest normalna.

IsPositiveInfinity(Double)

Zwraca wartość wskazującą, czy określona liczba ma wartość dodatnią nieskończoności.

IsPow2(Double)

Określa, czy wartość jest mocą dwóch.

IsSubnormal(Double)

Określa, czy określona wartość jest podnormalna.

Log(Double)

Oblicza wartość naturalną (logarytm base-E ).

Log(Double, Double)

Oblicza logarytm wartości w określonej bazie.

Log10(Double)

Oblicza logarytm base-10 wartości.

Log2(Double)

Oblicza dziennik2 wartości.

Max(Double, Double)

Porównuje dwie wartości z obliczeniami, które są większe.

MaxMagnitude(Double, Double)

Porównuje dwie wartości z obliczeniami, które są większe.

Min(Double, Double)

Porównuje dwie wartości z obliczeniami, które są mniejsze.

MinMagnitude(Double, Double)

Porównuje dwie wartości z obliczeniami, które są mniejsze.

Parse(ReadOnlySpan<Char>, IFormatProvider)

Analizuje zakres znaków w wartości.

Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider)

Konwertuje zakres znaków, który zawiera reprezentację ciągu liczby w określonym stylu i formacie specyficznym dla kultury na równoważność liczb zmiennoprzecinkowych o podwójnej precyzji.

Parse(String)

Konwertuje ciąg reprezentujący liczbę na odpowiadającą mu liczbę zmiennoprzecinkową podwójnej precyzji.

Parse(String, IFormatProvider)

Konwertuje reprezentację ciągu liczby w określonym formacie specyficznym dla kultury na równoważność liczb zmiennoprzecinkowych o podwójnej precyzji.

Parse(String, NumberStyles)

Konwertuje reprezentację ciągu liczby w określonym stylu na równoważną liczbę zmiennoprzecinkową o podwójnej precyzji.

Parse(String, NumberStyles, IFormatProvider)

Konwertuje reprezentację ciągu liczby w określonym stylu i formacie specyficznym dla kultury na równoważność liczb zmiennoprzecinkowych o podwójnej precyzji.

Pow(Double, Double)

Oblicza wartość podniesioną do danej mocy.

ReciprocalEstimate(Double)

Oblicza oszacowanie wzajemnej wartości.

ReciprocalSqrtEstimate(Double)

Oblicza oszacowanie wzajemnego pierwiastek kwadratowy wartości.

Round(Double)

Zaokrągla wartość do najbliższej liczby całkowitej przy użyciu domyślnego trybu zaokrąglania (ToEven).

Round(Double, Int32)

Zaokrągla wartość do określonej liczby cyfr ułamkowych przy użyciu domyślnego trybu zaokrąglania (ToEven).

Round(Double, Int32, MidpointRounding)

Zaokrągla wartość do określonej liczby cyfr ułamkowych przy użyciu domyślnego trybu zaokrąglania (ToEven).

Round(Double, MidpointRounding)

Zaokrągla wartość do najbliższej liczby całkowitej przy użyciu określonego trybu zaokrąglania.

ScaleB(Double, Int32)

Oblicza iloczyn wartości i jego promienia podstawowego podniesionego do określonej mocy.

Sign(Double)

Oblicza znak wartości.

Sin(Double)

Oblicza sinus wartości.

SinCos(Double)

Oblicza sinus i cosinus wartości.

Sinh(Double)

Oblicza sinus hiperboliczny wartości.

Sqrt(Double)

Oblicza pierwiastek kwadratowy wartości.

Tan(Double)

Oblicza tangens wartości.

Tanh(Double)

Oblicza tangens hiperboliczny wartości.

ToString()

Konwertuje wartość liczbową tego wystąpienia na równoważną reprezentację w postaci ciągu.

ToString(IFormatProvider)

Konwertuje wartość liczbową tego wystąpienia na równoważną reprezentację w postaci ciągu przy użyciu podanych danych formatowania specyficznych dla kultury.

ToString(String)

Konwertuje wartość liczbową tego wystąpienia na równoważną reprezentację w postaci ciągu przy użyciu podanego formatu.

ToString(String, IFormatProvider)

Konwertuje wartość liczbową tego wystąpienia na równoważną reprezentację w postaci ciągu przy użyciu podanego formatu i informacji specyficznych dla kultury.

Truncate(Double)

Obcina wartość.

TryCreate<TOther>(TOther, Double)

Próbuje utworzyć wystąpienie bieżącego typu na podstawie wartości.

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

Próbuje sformatować wartość bieżącego podwójnego wystąpienia na podany zakres znaków.

TryParse(ReadOnlySpan<Char>, Double)

Konwertuje reprezentację zakresu liczby w określonym stylu i formacie specyficznym dla kultury na równoważność liczb zmiennoprzecinkowych o podwójnej precyzji. Zwracana wartość wskazuje, czy konwersja powiodła się czy nie.

TryParse(ReadOnlySpan<Char>, IFormatProvider, Double)

Próbuje przeanalizować zakres znaków w wartości.

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

Konwertuje zakres znaków zawierający reprezentację ciągu liczby w określonym stylu i formacie specyficznym dla kultury na równoważność liczb zmiennoprzecinkowych o podwójnej precyzji. Zwracana wartość wskazuje, czy konwersja powiodła się czy nie.

TryParse(String, Double)

Konwertuje ciąg reprezentujący liczbę na odpowiadającą mu liczbę zmiennoprzecinkową podwójnej precyzji. Zwracana wartość wskazuje, czy konwersja powiodła się czy nie.

TryParse(String, IFormatProvider, Double)
TryParse(String, NumberStyles, IFormatProvider, Double)

Konwertuje reprezentację ciągu liczby w określonym stylu i formacie specyficznym dla kultury na równoważność liczb zmiennoprzecinkowych o podwójnej precyzji. Zwracana wartość wskazuje, czy konwersja powiodła się czy nie.

Operatory

Equality(Double, Double)

Zwraca wartość wskazującą, czy dwie określone Double wartości są równe.

GreaterThan(Double, Double)

Zwraca wartość wskazującą, czy określona Double wartość jest większa niż inna określona Double wartość.

GreaterThanOrEqual(Double, Double)

Zwraca wartość wskazującą, czy określona Double wartość jest większa lub równa innej określonej Double wartości.

Inequality(Double, Double)

Zwraca wartość wskazującą, czy dwie określone Double wartości nie są równe.

LessThan(Double, Double)

Zwraca wartość wskazującą, czy określona Double wartość jest mniejsza niż inna określona Double wartość.

LessThanOrEqual(Double, Double)

Zwraca wartość wskazującą, czy określona Double wartość jest mniejsza niż lub równa innej określonej Double wartości.

Jawne implementacje interfejsu

IComparable.CompareTo(Object)

Porównuje bieżące wystąpienie z innym obiektem tego samego typu i zwraca liczbę całkowitą, która wskazuje, czy bieżące wystąpienie poprzedza, następuje po lub występuje w tym samym położeniu, co inny obiekt w porządku sortowania.

IConvertible.GetTypeCode()

Zwraca wartość TypeCode dla tego wystąpienia.

IConvertible.ToBoolean(IFormatProvider)

Aby uzyskać opis tego członka, zobacz ToBoolean(IFormatProvider).

IConvertible.ToByte(IFormatProvider)

Aby uzyskać opis tego członka, zobacz ToByte(IFormatProvider).

IConvertible.ToChar(IFormatProvider)

Ta konwersja nie jest obsługiwana. Próba użycia tej metody zgłasza błąd InvalidCastException.

IConvertible.ToDateTime(IFormatProvider)

Ta konwersja nie jest obsługiwana. Próba użycia tej metody zgłasza błąd InvalidCastException.

IConvertible.ToDecimal(IFormatProvider)

Aby uzyskać opis tego członka, zobacz ToDecimal(IFormatProvider).

IConvertible.ToDouble(IFormatProvider)

Aby uzyskać opis tego członka, zobacz ToDouble(IFormatProvider).

IConvertible.ToInt16(IFormatProvider)

Aby uzyskać opis tego członka, zobacz ToInt16(IFormatProvider).

IConvertible.ToInt32(IFormatProvider)

Aby uzyskać opis tego członka, zobacz ToInt32(IFormatProvider).

IConvertible.ToInt64(IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToInt64(IFormatProvider).

IConvertible.ToSByte(IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToSByte(IFormatProvider).

IConvertible.ToSingle(IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToSingle(IFormatProvider).

IConvertible.ToType(Type, IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToType(Type, IFormatProvider).

IConvertible.ToUInt16(IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToUInt16(IFormatProvider).

IConvertible.ToUInt32(IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToUInt32(IFormatProvider).

IConvertible.ToUInt64(IFormatProvider)

Aby uzyskać opis tego elementu członkowskiego, zobacz ToUInt64(IFormatProvider).

IFloatingPoint<Double>.GetExponentByteCount()

Pobiera liczbę bajtów, które zostaną zapisane w ramach TryWriteExponentLittleEndian(Span<Byte>, Int32)elementu .

IFloatingPoint<Double>.GetExponentShortestBitLength()

Pobiera długość, w bitach, najkrótszej reprezentacji dwuczęściowej reprezentacji bieżącego wykładnika.

IFloatingPoint<Double>.GetSignificandBitLength()

Pobiera długość w bitach bieżącego znaku.

IFloatingPoint<Double>.GetSignificandByteCount()

Pobiera liczbę bajtów, które zostaną zapisane w ramach TryWriteSignificandLittleEndian(Span<Byte>, Int32)elementu .

IFloatingPoint<Double>.TryWriteExponentLittleEndian(Span<Byte>, Int32)

Próbuje napisać bieżący wykładnik w formacie mało endianu do danego zakresu.

IFloatingPoint<Double>.TryWriteSignificandLittleEndian(Span<Byte>, Int32)

Próbuje napisać bieżący znak, w małym formacie endian, do danego zakresu.

Dotyczy

Bezpieczeństwo wątkowe

Wszystkie elementy członkowskie tego typu są bezpieczne wątkowo. Elementy członkowskie, które na pierwszy rzut oka modyfikują stan wystąpienia, w rzeczywistości zwracają nowe wystąpienie zainicjowane z nową wartością. Podobnie jak w przypadku innych typów odczytywanie i zapisywanie w udostępnionej zmiennej, która zawiera wystąpienie tego typu, musi być chronione przez blokadę w celu zagwarantowania bezpieczeństwa wątków.

Zobacz też