Double 構造体

定義

倍精度浮動小数点数を表します。

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, IConvertible, IFormattable
public value class double : IComparable, IComparable<double>, IEquatable<double>, IFormattable
public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, ISpanFormattable
[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
[<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 IComparable, IConvertible, IFormattable
Public Structure Double
Implements IComparable, IComparable(Of Double), IEquatable(Of Double), IFormattable
継承
Double
属性
実装

の使用例を次のコード例に示します 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;
        }
    }
}
' 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

注釈

Double値型は、負の 1.79769313486232 e308 から正の 1.79769313486232 e308 までの値、正または負の0、 PositiveInfinity 、、() ではない値を持つ倍精度64ビット数値を表し NegativeInfinity NaN ます。 これは、非常に大きな値 (惑星または galaxies 間の距離など) または非常に小さい値 (キログラムの物質の分子質量など) を表すことを目的としており、多くの場合、(地球から別の太陽システムへの距離など) 不正確になることがあります。 この Double 型は、バイナリ浮動小数点演算の IEC 60559:1989 (IEEE 754) 標準に準拠しています。

このトピックは、次のセクションで構成されています。

Floating-Point 表現と有効桁数

データ型では、 Double 次の表に示すように、倍精度浮動小数点値が64ビットのバイナリ形式で格納されます。

パーツ Bits
有効桁または仮数 0-51
指数 52-62
符号 (0 = 正、1 = 負) 63

10分の分数では、一部の小数部 (1/3 やなど) を正確に表すことができないのと同様に Math.PI 、バイナリの分数では小数部の値を表すことができません。 たとえば、小数点として .1 によって正確に表される1/10 は、001100110011によって "0011" というパターンで無限大として表現されます。 この場合、浮動小数点値は、それが表す数値の不正確な表現を提供します。 多くの場合、元の浮動小数点値に対して追加の数学演算を実行すると、精度が低下する傾向があります。 たとえば、0.1 を10に乗算した結果を比較し、.1 を. 1 9 回追加した場合、その加算には8個の操作が含まれているため、精度が低下していることがわかります。 この不均衡は、 Double "R" 標準の数値書式指定文字列を使用して2つの値を表示する場合にのみ表示されます。必要に応じて、型でサポートされている17桁のすべての有効桁数が表示され Double ます。

using System;

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

      Console.WriteLine(".1 * 10:           {0:R}", result1);
      Console.WriteLine(".1 Added 10 times: {0:R}", result2);
   }
}
// The example displays the following output:
//       .1 * 10:           1
//       .1 Added 10 times: 0.99999999999999989
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

一部の数値は小数部のバイナリ値として正確に表すことができないため、浮動小数点数は実数のみを概数にすることができます。

すべての浮動小数点数には、有効桁数も制限されています。これにより、浮動小数点値が実数を近似する精度も決まります。 値の有効桁数は最大 Double で15桁ですが、内部的には最大17桁が保持されます。 これは、浮動小数点演算によっては、浮動小数点値を変更するための有効桁数が不足している場合があることを意味します。 具体的な例を次に示します。 非常に大きな浮動小数点値を定義し、の積と Double.Epsilon 1 つの quadrillion を追加します。 ただし、この製品では、元の浮動小数点値を変更することはできません。 最下位桁は1000桁ですが、製品の最上位桁は 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
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

浮動小数点数の有効桁数には、次のような結果があります。

  • 特定の有効桁数で等しく見える 2 つの浮動小数点数が、最小有効数字が異なっているために等しくない場合があります。 次の例では、一連の数値が加算され、それらの合計が予想される合計と比較されます。 2つの値は同じように見えますが、メソッドを呼び出すと、その値 Equals がではないことが示されます。

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

    ステートメント内の書式項目を Console.WriteLine(String, Object, Object) およびからに変更 {0}{1} {0:R} て、 {1:R} 2 つの値のすべての有効桁数を表示すると Double 、加算演算中に精度が低下しているため、2つの値が等しくないことが明らかになります。 この場合、比較を実行する前に、メソッドを呼び出して、値を目的の精度に丸めることによって問題を解決でき Math.Round(Double, Int32) Double ます。

  • 浮動小数点数を使用する数学的演算または比較演算では、10進数が使用されている場合、同じ結果が得られないことがあります。これは、バイナリ浮動小数点数が10進数と等しくない可能性があるためです。 前の例では、0.1 を10で乗算し、を1回追加した結果を表示しています。

    小数部の値を持つ数値演算の精度が重要な場合は、型ではなくを使用でき Decimal Double ます。 型または型の範囲を超える整数値を持つ数値演算の精度 Int64 UInt64 が重要な場合は、型を使用し BigInteger ます。

  • 浮動小数点数が含まれている場合、値はラウンドトリップしない可能性があります。 操作が元の浮動小数点数を別の形式に変換した場合、逆の演算で変換後の形式が浮動小数点数に変換され、最後の浮動小数点数が元の浮動小数点数と等しくない場合、値はラウンドトリップと呼ばれます。 変換で1つ以上の有効桁が失われたり、変更されたりすると、ラウンドトリップが失敗する可能性があります。 次の例では、3つの Double 値が文字列に変換され、ファイルに保存されます。 ただし、出力に示されているように、値が同一であるように見える場合でも、復元された値は元の値と同じではありません。

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

    この場合、次の例に示すように、値の完全な有効桁数を保持するために "G17" 標準の数値書式指定文字列 を使用すると、値が正常にラウンドトリップされることがあり Double ます。

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

重要

値と共に使用する場合 Double 、場合によっては、"R" 書式指定子が元の値のラウンドトリップに失敗することがあります。 値が正常にラウンドトリップされるようにするには Double 、"G17" 書式指定子を使用します。

  • Single 値の有効桁数が Double 値を下回っています。 Single多くの場合、一見同等の値に変換される値は、 Double 精度が異なるため、値と等しくありません Double 。 次の例では、同じ除算演算の結果がとの値に割り当てられてい Double Single ます。 Single値がにキャストされた後 Double 、2つの値の比較によって等しくないことが示されます。

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

    この問題を回避するには、 Double データ型の代わりにを使用するか、メソッドを使用して Single 両方の値の Round 有効桁数を同じにします。

また、型の有効桁数が失われるため、値を持つ算術演算と代入演算の結果は、 Double プラットフォームによって若干異なる場合があり Double ます。 たとえば、リテラル値を代入した結果は、 Double .NET Framework の32ビットバージョンと64ビットバージョンで異なる場合があります。 次の例では、リテラル値 4.42330604244772 E-305 と、値が-4.42330604244772 E-305 である変数が変数に割り当てられている場合の違いを示し Double ます。 この場合のメソッドの結果は、 Parse(String) 精度の低下による影響を受けないことに注意してください。

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

等しいかどうかのテスト

等しいと見なされるためには、2つの Double 値が同一の値を表す必要があります。 ただし、値間の精度が異なるため、または1つまたは両方の値によって精度が低下していることが原因で、浮動小数点値が同一であることが予想される場合は、少なくとも有効桁数が異なるために等しくならないことがあります。 結果として、 Equals 2 つの値が等しいかどうかを判断するためにメソッドを呼び出し、2つの値の間の関係を判断するためにメソッドを呼び出すと、 CompareTo 多くの場合、 Double 予期しない結果が発生します。 これは、次の例では明らかです。2つの目に等しい値は、 Double 最初の精度が15桁で、2番目の値が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
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

異なるコードパスに従い、異なる方法で操作される計算値は、多くの場合、等しくないことが証明されます。 次の例では、1つの Double 値が二乗で、平方根が計算され、元の値が復元されます。 2番目の Double は、結果の平方根が3.51 で除算され、元の値が復元される前に、3.51 と二乗が乗算されます。 2つの値は同一であるように見えますが、メソッドを呼び出すと、それらの値 Equals(Double) が等しくないことが示されます。 "R" 標準書式指定文字列を使用して、各 Double 値のすべての有効桁数を表示する結果文字列を返すと、2番目の値が .0000000000001 未満であることが示されます。

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

精度の低下が比較の結果に影響する可能性がある場合は、次のいずれかの方法を使用して、メソッドまたはメソッドを呼び出すことができ Equals CompareTo ます。

  • Math.Round2 つの値の有効桁数が同じであることを確認するには、メソッドを呼び出します。 次の例では、この方法を使用するように前の例を変更し、2つの小数部の値が等価になるようにしています。

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

    精度の問題は、中間値の丸めにも適用されます。 詳細については、Math.Round(Double, Int32, MidpointRounding) メソッドを参照してください。

  • 等価ではなく、おおよその等価性をテストします。 そのためには、2つの値が異なる一方でも同じである必要がある絶対金額を定義するか、小さい値が大きな値から逸脱する相対的な量を定義する必要があります。

    警告

    Double.Epsilon は、 Double 等しいかどうかをテストするときに2つの値の間の距離の絶対測定値として使用されることがあります。 ただし、は、 Double.Epsilon 値がゼロであるに加算または減算できる最小値を測定し Double ます。 正および負の値について Double は、の値 Double.Epsilon が小さすぎて検出できません。 したがって、値がゼロの場合を除いて、等しいかどうかのテストでは使用しないことをお勧めします。

    次の例では、後者の方法を使用して、 IsApproximatelyEqual 2 つの値の相対差をテストするメソッドを定義しています。 また、メソッドとメソッドの呼び出しの結果も比較し IsApproximatelyEqual Equals(Double) ます。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          double one1 = .1 * 10;
          double one2 = 0;
          for (int ctr = 1; ctr <= 10; ctr++)
             one2 += .1;
    
          Console.WriteLine("{0:R} = {1:R}: {2}", one1, one2, one1.Equals(one2));
          Console.WriteLine("{0:R} is approximately equal to {1:R}: {2}",
                            one1, one2,
                            IsApproximatelyEqual(one1, one2, .000000001));
       }
    
       static bool IsApproximatelyEqual(double value1, double value2, double epsilon)
       {
          // If they are equal anyway, just return True.
          if (value1.Equals(value2))
             return true;
    
          // Handle NaN, Infinity.
          if (Double.IsInfinity(value1) | Double.IsNaN(value1))
             return value1.Equals(value2);
          else if (Double.IsInfinity(value2) | Double.IsNaN(value2))
             return value1.Equals(value2);
    
          // Handle zero to avoid division by zero
          double divisor = Math.Max(value1, value2);
          if (divisor.Equals(0))
             divisor = Math.Min(value1, value2);
    
          return Math.Abs((value1 - value2) / divisor) <= epsilon;
       }
    }
    // The example displays the following output:
    //       1 = 0.99999999999999989: False
    //       1 is approximately equal to 0.99999999999999989: True
    
    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
    

Floating-Point の値と例外

オーバーフローや0による除算などの無効な操作で例外をスローする整数型の操作とは異なり、浮動小数点値を持つ演算では、例外はスローされません。 代わりに、例外的な状況では、浮動小数点演算の結果は0、正の無限大、負の無限大、または非数 (NaN) のようになります。

  • 浮動小数点演算の結果が変換先の形式に対して小さすぎる場合、結果は0になります。 これは、次の例に示すように、2つの非常に小さい数値が乗算された場合に発生する可能性があります。

    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
    
    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
    
  • 浮動小数点演算の結果の大きさが変換先の形式の範囲を超える場合、演算の結果は、 PositiveInfinity NegativeInfinity 結果の符号に応じてまたはになります。 次の例に示すように、オーバーフローする操作の結果 Double.MaxValue PositiveInfinity と、オーバーフローする操作の結果はになり Double.MinValue NegativeInfinity ます。

    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
    
    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 また、0による正の被除数の除算によって結果が得ら NegativeInfinity れ、0による除算の結果が負の被除数と共に返されます。

  • 浮動小数点演算が無効な場合、演算の結果はに NaN なります。 たとえば、 NaN 次の操作の結果が返されます。

    • 被除数が0の0による除算。 0による除算のその他のケースでは、またはのいずれかになり PositiveInfinity NegativeInfinity ます。
  • 無効な入力を持つ任意の浮動小数点演算。 たとえば、負の値を指定してメソッドを呼び出す Math.Sqrt NaN と、が返されます。これは、1以上の値または負の値を持つメソッドを呼び出した場合と同じ Math.Acos です。

  • 値がである引数を持つすべての操作 Double.NaN

型変換と Double 構造体

構造体では、明示的または暗黙的な変換演算子は定義されません。代わりに、変換 Double はコンパイラによって実装されます。

プリミティブ数値型の値から への変換は拡大変換であるため、コンパイラが明示的に要求しない限り、明示的なキャスト演算子や変換メソッドの呼び出しは Double 必要ではありません。 たとえば、C# コンパイラでは、 から への変換にキャスト演算子が必要ですが、Visual Basic Decimal Double は必要ではありません。 次の例では、他のプリミティブ数値型の最小値または最大値を に変換します 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)
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)

さらに、、、および Single Single.NaNSingle.PositiveInfinity 値は Single.NegativeInfinity 、それぞれ Double.NaN Double.PositiveInfinity 、、および Double.NegativeInfinity に変換されます。

一部の数値型の値を値に変換すると、有効桁数が失 Double われる可能性があります。 例に示すように、および の値を値に変換すると、有効桁数 Decimal Int64 UInt64 が失われる可能性 Double があります。

値から他のプリミティブ数値データ型の値への変換は縮小変換であり、キャスト演算子 (C# の場合)、変換メソッド (Visual Basic 内)、またはメソッドの呼び出しが必要です。 Double Convert ターゲット型の プロパティと プロパティによって定義されるターゲット データ型の範囲外の値は、次の表に示すように MinValue MaxValue 動作します。

変換後の型 結果
任意の整数型 チェック OverflowException されたコンテキストで変換が発生した場合の例外。

変換がチェックされていないコンテキスト (C# の既定値) で発生した場合、変換操作は成功しますが、値はオーバーフローします。
Decimal OverflowException 例外。
Single Single.NegativeInfinity 負の値の場合は 。

Single.PositiveInfinity 正の値の場合は 。

さらに、、、および はチェックされたコンテキストで整数に変換するために をスローしますが、これらの値は、チェックされていないコンテキストで整数に変換すると Double.NaN Double.PositiveInfinity Double.NegativeInfinity OverflowException オーバーフローします。 への変換では Decimal 、常に がスローされます OverflowException 。 への変換では Single 、それぞれ Single.NaN Single.PositiveInfinity 、、および Single.NegativeInfinity に変換されます。

有効桁数が失われると、値が別の数値型 Double に変換される可能性があります。 いずれかの整数型に変換する場合、例の出力に示すように、値が丸められたり (Visual Basic のように) 切り捨てられたりすると、小数部の部分は失われます (C# の場合と同様 Double )。 と の値への変換では、ターゲット データ型の値が Decimal Single Double 正確に表現されない場合があります。

次の例では、多数の値を他 Double のいくつかの数値型に変換します。 変換は、(既定の) Visual Basic(checked キーワードが理由で) C# のチェック されたコンテキストで発生します。 この例の出力は、チェックされていない両方のコンテキストでの変換の結果を示しています。 コンパイラ スイッチと C# で ステートメントをコメントアウトしてコンパイルすることで、Visual Basic のチェックされていないコンテキストで変換 /removeintchecks+ を実行 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)
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)

数値型の変換の詳細については、「変換テーブルの型変換」および「型変換.NET Frameworkを参照してください

Floating-Point機能

構造体 Double と関連する型は、次の領域で操作を実行するメソッドを提供します。

  • 値 の比較。 メソッドを呼び出して、2 つの値が等しいかどうかを判断するか、 メソッドを呼び出して 2 つの値間の Equals Double CompareTo 関係を判断できます。

    構造体 Double は、比較演算子の完全なセットもサポートしています。 たとえば、等値または不等値をテストしたり、1 つの値が別の値以上かどうかを判断できます。 オペランドの 1 つが 以外の数値型の場合、比較を実行する前に に Double Double 変換されます。

    警告

    精度の違いにより、等しいと予想される 2 つの値が等しくない可能性があります。これは比較の結果 Double に影響します。 2 つの 値の比較の 詳細については、「等値のテスト」セクションを Double 参照してください。

    、、、および IsNaN メソッドを IsInfinityIsPositiveInfinityIsNegativeInfinity 出して、これらの特殊な値をテストすることもできます。

  • 数学演算。 加算、減算、乗算、除算などの一般的な算術演算は、メソッドではなく、言語コンパイラと共通中間言語 (CIL) 命令によって Double 実装されます。 数学演算のオペランドの 1 つが 以外の数値型の場合、演算を実行する前に に Double Double 変換されます。 操作の結果も値 Double になります。

    その他の数学演算は、 クラスで static ( Shared Visual Basic) メソッドを呼び出すことによって実行 System.Math できます。 これには、算術演算 (、 など)、geometry (や など)、および微円 (など) に一般的に使用される追加のメソッドが Math.Abs Math.Sign Math.Sqrt Math.Cos Math.Sin 含まれます Math.Log

    値内の個々のビットを操作 Double できます。 メソッド BitConverter.DoubleToInt64Bits は、値 Double のビット パターンを 64 ビット整数で保持します。 メソッド BitConverter.GetBytes(Double) は、バイト配列内のビット パターンを返します。

  • の丸め。 丸めは、多くの場合、浮動小数点表現と精度の問題によって引き起こされる値間の差の影響を軽減する手法として使用されます。 メソッドを呼び出 Double すことによって、値を丸 Math.Round めできます。

  • の書式設定。 メソッドを呼び出すことによって、または複合書式設定機能を使用して、値を文字列 Double ToString 形式に変換できます。 書式指定文字列が浮動小数点値の文字列表現を制御する方法については、「標準数値書式指定文字列」および「カスタム数値書式 指定 文字列」の トピックを参照 してください。

  • 文字列 の解析。 または メソッドを呼び出すことによって、浮動小数点値の文字列形式を値 DoubleParse 変換 TryParse できます。 解析操作が失敗した場合、 Parse メソッドは例外をスローし、 メソッド TryParse は を返します false

  • 型変換。 構造体 Double は、 インターフェイスの明示的なインターフェイス実装を提供します。このインターフェイスは、任意の 2 つの標準データ型とデータ型.NET Framework IConvertible サポートします。 言語コンパイラでは、他のすべての標準数値型の値から値への暗黙的な変換もサポート Double されています。 標準数値型の値から への変換は拡大変換であり、キャスト演算子または変換メソッドのユーザー Double は必要ではありません。

    ただし、 と の値 Int64Single 変換では、精度が失われる可能性があります。 次の表に、これらの各型の有効桁数の違いを示します。

    種類 最大有効桁数 内部精度
    Double 15 17
    Int64 19 桁の 10 進数 19 桁の 10 進数
    Single 7 桁の 10 進数 9 桁の 10 進数

    有効桁数の問題は、値に変換 Single される値に最も頻繁に影響 Double します。 次の例では、同じ除算演算によって生成される 2 つの値は等しくない値です。値の 1 つが に変換された単精度浮動小数点値なのでです Double

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

フィールド

Epsilon

ゼロより大きい最小の Double 値を表します。 このフィールドは定数です。

MaxValue

Double の最大有効値を表します。 このフィールドは定数です。

MinValue

Double の最小有効値を表します。 このフィールドは定数です。

NaN

非数 (NaN) の値を表します。 このフィールドは定数です。

NegativeInfinity

負の無限大を表します。 このフィールドは定数です。

PositiveInfinity

正の無限大を表します。 このフィールドは定数です。

メソッド

CompareTo(Double)

このインスタンスと指定した倍精度浮動小数点数を比較し、このインスタンスの値が指定した倍精度浮動小数点数の値よりも小さいか、同じか、または大きいかを示す整数を返します。

CompareTo(Object)

このインスタンスと指定したオブジェクトを比較し、このインスタンスの値が指定したオブジェクトの値よりも小さいか、同じか、または大きいかを示す整数を返します。

Equals(Double)

このインスタンスと指定した Double オブジェクトが同じ値を表しているかどうかを示す値を返します。

Equals(Object)

このインスタンスが指定されたオブジェクトに等しいかどうかを示す値を返します。

GetHashCode()

このインスタンスのハッシュ コードを返します。

GetTypeCode()

Double 値型の TypeCode を返します。

IsFinite(Double)

指定の値が有限 (ゼロ、非正規、または正規) かどうかを判断します。

IsInfinity(Double)

指定した数値が負または正の無限大と評価されるかどうかを示す値を返します。

IsNaN(Double)

指定した値が非数値 (NaN) かどうかを示す値を返します。

IsNegative(Double)

指定した値が負かどうかを判断します。

IsNegativeInfinity(Double)

指定した数値が負の無限大と評価されるかどうかを示す値を返します。

IsNormal(Double)

指定した値が正規かどうかを判断します。

IsPositiveInfinity(Double)

指定した数値が正の無限大と評価されるかどうかを示す値を返します。

IsSubnormal(Double)

指定した値が非正規かどうかを判断します。

Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider)

指定したスタイルおよびカルチャ固有の書式による数値の文字列表現を含む文字スパンを、等価の倍精度浮動小数点数に変換します。

Parse(String)

数値の文字列形式を、等価の倍精度浮動小数点数に変換します。

Parse(String, IFormatProvider)

指定したカルチャに固有の書式による数値の文字列形式を、それと等価な倍精度浮動小数点数に変換します。

Parse(String, NumberStyles)

数値の指定したスタイルでの文字列形式を、それと等価な倍精度浮動小数点数に変換します。

Parse(String, NumberStyles, IFormatProvider)

指定したスタイルおよびカルチャ固有の書式での数値の文字列形式を、等価の倍精度浮動小数点数に変換します。

ToString()

このインスタンスの数値を、それと等価な文字列形式に変換します。

ToString(IFormatProvider)

このインスタンスの数値を、指定したカルチャ固有の書式情報を使用して、それと等価な文字列形式に変換します。

ToString(String)

指定した書式を使用して、このインスタンスの数値を、それと等価な文字列形式に変換します。

ToString(String, IFormatProvider)

このインスタンスの数値を、指定した書式およびカルチャ固有の書式情報を使用して、それと等価な文字列形式に変換します。

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

現在の double 型インスタンスの値の、指定した文字スパンへの書式設定を試みます。

TryParse(ReadOnlySpan<Char>, Double)

指定したスタイルおよびカルチャ固有の書式による数値のスパン表現を、等価の倍精度浮動小数点数に変換します。 戻り値は変換が成功したか失敗したかを示します。

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

指定したスタイルおよびカルチャ固有の書式による数値の文字列表現を含む文字スパンを、等価の倍精度浮動小数点数に変換します。 戻り値は変換が成功したか失敗したかを示します。

TryParse(String, Double)

数値の文字列形式を、等価の倍精度浮動小数点数に変換します。 戻り値は変換が成功したか失敗したかを示します。

TryParse(String, NumberStyles, IFormatProvider, Double)

指定したスタイルおよびカルチャ固有の書式での数値の文字列形式を、等価の倍精度浮動小数点数に変換します。 戻り値は変換が成功したか失敗したかを示します。

演算子

Equality(Double, Double)

指定した 2 つの Double 値が等しいかどうかを示す値を返します。

GreaterThan(Double, Double)

指定した Double 値が、指定したもう 1 つの Double 値より大きいかどうかを示す値を返します。

GreaterThanOrEqual(Double, Double)

指定した Double 値が、指定したもう 1 つの Double 値以上かどうかを示す値を返します。

Inequality(Double, Double)

指定した 2 つの Double 値が等しくないかどうかを示す値を返します。

LessThan(Double, Double)

指定した Double 値が、指定したもう 1 つの Double 値より小さいかどうかを示す値を返します。

LessThanOrEqual(Double, Double)

指定した Double 値が、指定したもう 1 つの Double 値以下かどうかを示す値を返します。

明示的なインターフェイスの実装

IComparable.CompareTo(Object)

現在のインスタンスを同じ型の別のオブジェクトと比較し、現在のインスタンスの並べ替え順序での位置が、比較対象のオブジェクトと比べて前か、後か、または同じかを示す整数を返します。

IConvertible.GetTypeCode()

インスタンスの TypeCode を返します。

IConvertible.ToBoolean(IFormatProvider)

このメンバーの詳細については、「ToBoolean(IFormatProvider)」をご覧ください。

IConvertible.ToByte(IFormatProvider)

このメンバーの詳細については、「ToByte(IFormatProvider)」をご覧ください。

IConvertible.ToChar(IFormatProvider)

この変換はサポートされていません。 このメソッドを使用しようとすると、InvalidCastException がスローされます。

IConvertible.ToDateTime(IFormatProvider)

この変換はサポートされていません。 このメソッドを使用しようとすると、InvalidCastException がスローされます。

IConvertible.ToDecimal(IFormatProvider)

このメンバーの詳細については、「ToDecimal(IFormatProvider)」をご覧ください。

IConvertible.ToDouble(IFormatProvider)

このメンバーの詳細については、「ToDouble(IFormatProvider)」をご覧ください。

IConvertible.ToInt16(IFormatProvider)

このメンバーの詳細については、「ToInt16(IFormatProvider)」をご覧ください。

IConvertible.ToInt32(IFormatProvider)

このメンバーの詳細については、「ToInt32(IFormatProvider)」をご覧ください。

IConvertible.ToInt64(IFormatProvider)

このメンバーの詳細については、「ToInt64(IFormatProvider)」をご覧ください。

IConvertible.ToSByte(IFormatProvider)

このメンバーの詳細については、「ToSByte(IFormatProvider)」をご覧ください。

IConvertible.ToSingle(IFormatProvider)

このメンバーの詳細については、「ToSingle(IFormatProvider)」をご覧ください。

IConvertible.ToType(Type, IFormatProvider)

このメンバーの詳細については、「ToType(Type, IFormatProvider)」をご覧ください。

IConvertible.ToUInt16(IFormatProvider)

このメンバーの詳細については、「ToUInt16(IFormatProvider)」をご覧ください。

IConvertible.ToUInt32(IFormatProvider)

このメンバーの詳細については、「ToUInt32(IFormatProvider)」をご覧ください。

IConvertible.ToUInt64(IFormatProvider)

このメンバーの詳細については、「ToUInt64(IFormatProvider)」をご覧ください。

適用対象

スレッド セーフ

この型のすべてのメンバーはスレッド セーフです。 インスタンスの状態を変更すると思えるメンバーは、実際には新しい値で初期化された新しいインスタンスを返します。 他の型と同様に、この型のインスタンスを含む共有変数の読み取りおよび書き込みは、スレッドセーフを保証するためにロックによって保護する必要があります。

こちらもご覧ください