Double Yapı
Tanım
Önemli
Bazı bilgiler ürünün ön sürümüyle ilgilidir ve sürüm öncesinde önemli değişiklikler yapılmış olabilir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.
Çift duyarlıklı kayan noktalı sayıyı temsil eder.
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
- Devralma
- Öznitelikler
- Uygulamalar
Örnekler
Aşağıdaki kod örneği kullanımını Double göstermektedir:
// 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
Açıklamalar
DoubleDeğer türü, pozitif veya negatif sıfır,, PositiveInfinity NegativeInfinity , ve sayı () değil, negatif 1.79769313486232 E308 ile pozitif 1.79769313486232 E308 arasında değişen değerleri olan çift duyarlıklı 64 bitlik bir sayıyı temsil eder NaN . Son derece büyük (örneğin, planorlar veya galakileri) ya da son derece küçük (örneğin, dünya çapında başka bir Solar sistemine olan mesafe) olan değerleri temsil etmek için tasarlanmıştır. DoubleTür, ikili kayan nokta aritmetiği IÇIN ıec 60559:1989 (ıeee 754) standardına uyar.
Bu konu aşağıdaki bölümlerden oluşur:
Kayan Nokta Gösterimi ve Duyarlık
DoubleVeri türü, aşağıdaki tabloda gösterildiği gibi, çift duyarlıklı kayan nokta değerlerini 64 bitlik ikili biçimde depolar:
Bölüm | Bits |
---|---|
Mantisinin veya Mantis | 0-51 |
Üs | 52-62 |
İmzala (0 = pozitif, 1 = negatif) | 63 |
Ondalık kesirler, bazı kesirli değerleri (örneğin, 1/3 veya) tam olarak temsil etmediği için Math.PI , ikili kesirler bazı kesirli değerleri temsil etmez. Örneğin, bir ondalık kesir olarak 1. tarafından tam olarak temsil edilen 1/10, "0011" adlı bir "" düzeniyle sonsuzluk olarak. 001100110011. Bu durumda, kayan nokta değeri, temsil ettiği sayının kesin bir gösterimini sağlar. Özgün kayan nokta değeri üzerinde ek matematik işlemleri gerçekleştirmek genellikle duyarlık olmaması eğilimi gösterir. Örneğin, 1. ve 1.1 9 kez çarpmadan elde edilen sonucu karşılaştırdığımızda, daha fazla sayıda işlem olduğu için bu ek, daha az kesin sonuç ürettiğinden, bu eklemeyi gördük. Bu ayırmanın yalnızca, Double gerekli olan "R" Standart sayısal biçim dizesikullanılarak görüntülendiğine, ancak gerekirse, tür tarafından desteklenen tüm 17 hassasiyetini görüntülemesi gerektiğini unutmayın 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
Bazı sayılar tam olarak kesirli ikili değerler olarak temsil edilemediğinden, kayan noktalı sayılar yalnızca gerçek sayıları tahmin edebilir.
Tüm kayan noktalı sayıların da sınırlı sayıda önemli basamak vardır ve bu da doğru bir kayan nokta değerinin gerçek bir sayıya ne kadar yakın olduğunu belirler. Bir Double değer en fazla 15 ondalık basamağa sahiptir, ancak dahili olarak en fazla 17 basamak saklanır. Yani, bazı kayan nokta işlemlerinde bir kayan nokta değerini değiştirmek için duyarlık yetersiz olabilir. Aşağıdaki örnek, bir gösterim sağlar. Çok büyük bir kayan nokta değeri tanımlar ve sonra ürünü Double.Epsilon ve bir quadrillion öğesini ekler. Ancak, ürün orijinal kayan nokta değerini değiştirmek için çok küçük. En az önemli basamak binde, ancak üründeki en önemli basamak 10-309' dur.
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
Kayan noktalı sayının sınırlı duyarlığı birkaç sonuçlara sahiptir:
Belirli bir duyarlık için eşit olarak görünen iki kayan nokta numarası, en az önemli basamaklar farklı olduğu için eşit olarak karşılaştırmayabilir. Aşağıdaki örnekte, bir dizi sayı birlikte eklenir ve toplamı beklenen toplam ile karşılaştırılır. İki değer aynı gibi görünse de yöntemine yapılan bir çağrı olmadığını
Equals
gösterir.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)Deyimdeki biçim öğelerini ve ' den ' e değiştirirseniz
{0}
{1}
{0:R}
ve{1:R}
iki değerin tüm önemli rakamlarını görüntülediğinizde Double , toplama işlemleri sırasında duyarlık kaybı nedeniyle iki değerin eşit olduğundan net olur. Bu durumda, bu sorun, Math.Round(Double, Int32) Double karşılaştırmayı gerçekleştirmeden önce değerleri istenen duyarlığa yuvarlamak için metodu çağırarak çözülebilir.Kayan noktalı sayı kullanan matematik veya karşılaştırma işlemi, bir ondalık sayı kullanılırsa, ikili kayan noktalı sayı ondalık sayıya eşit olmadığı için aynı sonucu ortaya çıkabilir. Önceki bir örnek, 1 ile 10 çarpılmasıyla ve 1 kez eklenerek bunu gösteriliyor.
Kesirli değerlere sahip sayısal işlemlerdeki doğruluk önemli olduğunda, Decimal türü yerine kullanabilirsiniz Double . Ya da tür aralığının ötesinde tamsayı değerleri olan sayısal işlemlerdeki doğruluk Int64 önemli olduğunda UInt64 , BigInteger türü kullanın.
Bir kayan noktalı sayı varsa bir değer gidiş dönüş olmayabilir. Bir işlem özgün kayan noktalı sayıyı başka bir forma dönüştürdüğünde, bir değer gidiş dönüş olarak kabul edilir, ters işlem dönüştürülen formu bir kayan noktalı sayıya geri dönüştürür ve son kayan noktalı sayı orijinal kayan noktalı sayıya eşit değildir. Bir dönüşümde bir veya daha fazla en az önemli basamak kaybolduğu veya değiştiği için gidiş dönüş başarısız olabilir. Aşağıdaki örnekte, üç Double değer dizelere dönüştürülür ve bir dosyaya kaydedilir. Ancak Çıktının gösterdiği gibi, değerler aynı gibi görünse de, geri yüklenen değerler özgün değerlere eşit değildir.
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
Bu durumda, aşağıdaki örnekte gösterildiği gibi, değerlerin tam hassasiyetini korumak için "G17" Standart sayısal biçim dizesi kullanılarak değerler başarıyla yuvarlayabilirsiniz 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
Önemli
Bir Double değerle kullanıldığında, bazı durumlarda "R" Biçim belirleyicisi özgün değeri başarıyla geri dönmez. Değerlerin başarılı bir şekilde gidiş dönüş olmasını sağlamak için Double "G17" biçim belirticisini kullanın.
Single değerler değerlere kıyasla daha az duyarlığa sahiptir Double . Single Double Double Doğruluk farklılıklarının farklılığı nedeniyle, bir benzer şekilde, genellikle bir eşdeğer değere dönüştürülmüş bir değer değere eşit değildir. Aşağıdaki örnekte, aynı bölme işlemlerinin sonucu bir Double ve bir Single değere atanır. SingleDeğer bir öğesine aktardıktan sonra Double , iki değerin karşılaştırılması eşit olduğunu gösterir.
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
Bu sorundan kaçınmak için, Double Single veri türünün yerinde kullanın veya Round yöntemini her iki değerin de aynı duyarlığa sahip olacak şekilde kullanın.
Ayrıca, aritmetik ve atama işlemlerinin sonuçları, Double tür duyarlık kaybı nedeniyle, platforma göre biraz farklı olabilir Double . Örneğin, bir sabit değer atamanın sonucu Double .NET Framework 32-bit ve 64-bit sürümlerinde farklı olabilir. Aşağıdaki örnekte,-4.42330604244772 E-305 sabit değeri ve değeri-4.42330604244772 E-305 olan bir değişken atandığında bu fark gösterilmektedir Double . Parse(String)Bu durumda yöntemin sonucunun duyarlık kaybını etkilemediğini unutmayın.
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
Eşitlik Sınaması
Eşit kabul edilmesi için, iki Double değer özdeş değerleri temsil etmelidir. Ancak, değerler arasındaki duyarlık farklılığı veya bir ya da her iki değerin bir duyarlık kaybı nedeniyle, aynı olması beklenen kayan nokta değerleri, en az önemli rakamlarla farklılıklar nedeniyle eşit olması beklenir. Sonuç olarak, Equals iki değerin eşit olup olmadığını veya CompareTo iki değer arasındaki ilişkiyi belirleme yöntemine yapılan çağrıları Double , genellikle beklenmeyen sonuçlara neden olduğunu anlamak için yöntemini çağırır. Bu, ikinci iki görünüşe Double göre eşit değerlere sahip olduğu için, ikincisi 17 ' ye sahip olduğu için, iki görünüşe göre eşit değerlerin eşit olduğu gibi bir şekilde, bu şekilde belirlenir.
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
Farklı kod yollarını izleyen ve farklı yollarla uygulanan Hesaplanmış değerler genellikle eşit olarak bir şekilde harcanacaktır. Aşağıdaki örnekte, bir Double değer kare içinde olur ve sonra özgün değeri geri yüklemek için kare kök hesaplanır. İkincisi, Double başlangıçtaki değeri geri yüklemek için 3,51 ile çarpılarak, sonucun kare kökü 3,51 ile bölünür. İki değer özdeş gibi görünse de yöntemine yapılan bir çağrı Equals(Double) eşit olmadığını gösterir. Her Iki değerin de tüm önemli basamaklarını görüntüleyen bir sonuç dizesi döndürmek için "R" standart biçim dizesinin kullanılması, ikinci değerin birinciden küçük .0000000000001 olduğunu gösterir.
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
Duyarlık kaybı bir karşılaştırmanın sonucunu etkilemesinin olası olduğu durumlarda, veya yöntemini çağırmak için aşağıdaki diğer seçenekleri benimseyebilirsiniz Equals CompareTo :
Math.RoundHer iki değerin de aynı duyarlığa sahip olduğundan emin olmak için yöntemini çağırın. Aşağıdaki örnek, iki kesirli değerin eşdeğer olması için bu yaklaşımı kullanmak üzere önceki bir örneği değiştirir.
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
Duyarlık sorunu, orta nokta değerlerinin yuvarlanması için hala geçerlidir. Daha fazla bilgi için bkz Math.Round(Double, Int32, MidpointRounding) . yöntemi.
Eşitlik yerine yaklaşık eşitlik için test edin. Bu, iki değerin farklı olmasına karşın eşit olmaya devam ettiği ya da daha küçük bir değerin daha büyük değerden ayırt edilebilen bir göreli miktarı tanımladığınız mutlak bir miktar tanımlamanızı gerektirir.
Uyarı
Double.Epsilon , bazen Double eşitlik için test edilirken iki değer arasındaki mesafeyi mutlak bir ölçü olarak kullanır. Ancak, Double.Epsilon değeri sıfır olan veya ondan çıkarılan en küçük olası değeri ölçer Double . Çoğu pozitif ve negatif Double değer için değeri Double.Epsilon algılanamayacak kadar küçüktür. Bu nedenle, sıfır olan değerler dışında, bir eşitlik için testlerin kullanımını önermiyoruz.
Aşağıdaki örnek,
IsApproximatelyEqual
iki değer arasındaki göreli farkı test eden bir yöntemi tanımlamak için ikinci yaklaşımı kullanır. Ayrıca yönteme ve yöntemine yapılan çağrıların sonucunu da karşıtdırIsApproximatelyEqual
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
Kayan Nokta Değerleri ve Özel Durumlar
Taşma veya sıfıra bölme gibi geçersiz işlemler için özel durum oluşturan integral türlerine sahip işlemlerden farklı olarak, kayan nokta değerlerine sahip işlemler özel durum oluşturmaz. Bunun yerine, bazı durumlarda kayan nokta işleminin sonucu sıfır, pozitif sonsuz, negatif sonsuz veya sayı değil (NaN):
Kayan noktalı bir işlemin sonucu hedef biçim için çok küçükse, sonuç sıfırdır. Bu, aşağıdaki örnekte gösterildiği gibi iki çok küçük sayı çarpıldığı zaman meydana gelebilir.
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
Bir kayan nokta işleminin sonucunun büyüklüğü hedef biçimin aralığını aşarsa, işlemin sonucu, PositiveInfinity NegativeInfinity sonucun işaretine uygun olarak veya olur. Aşağıdaki örnekte gösterildiği gibi, taşan bir işlemin sonucu Double.MaxValue PositiveInfinity ve taşan bir işlemin sonucu 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 Ayrıca, pozitif bir bölünen bir bölme ile sıfıra, sıfıra bölünen bir NegativeInfinity bölme de negatif bir bölünmeyle sonuçlanır.
Kayan noktalı bir işlem geçersizse, işlemin sonucu olur NaN . Örneğin, NaN aşağıdaki işlemlerin sonuçları:
- Sıfıra bölünen sıfıra bölme. Sıfıra göre bölme için diğer durumların ya da ya da ile sonuçlandığına unutmayın PositiveInfinity NegativeInfinity .
Geçersiz bir girişi olan herhangi bir kayan nokta işlemi. Örneğin, yöntemi negatif bir Math.Sqrt değer ile çağırmak NaN , Math.Acos bir değeri sıfırdan büyük veya negatif bir değer olan bir değerle çağırmak gibi döndürür.
Değeri olan bağımsız değişkenine sahip herhangi bir işlem Double.NaN .
Tür dönüştürmeleri ve çift yapı
Yapı herhangi bir açık veya örtülü dönüştürme işleci tanımlamaz; bunun yerine, Double dönüştürmeler derleyici tarafından uygulanır.
Herhangi bir temel sayısal türün değerinin bir değerine dönüştürmesi bir genişleten dönüştürmedir ve bu nedenle bir derleyici açıkça gerektirmediği sürece açık bir tür dönüştürme işleci veya dönüştürme yöntemine çağrı Double gerektirmez. Örneğin, C# derleyicisi, 'den 'ye dönüştürmeler için bir tür dönüştürme Decimal Double işleci gerektirirken, Visual Basic derleyicisi bunu gerektirmez. Aşağıdaki örnek, diğer temel sayısal türlerin en düşük veya en yüksek değerini bir değerine Double dönüştürür.
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)
Ayrıca , Single ve Single.NaN değerleri Single.PositiveInfinity Single.NegativeInfinity sırasıyla , ve Double.NaN Double.PositiveInfinity Double.NegativeInfinity değerlerine dönüştürülür.
Bazı sayısal türlerin değerinin bir değere dönüştürme işleminin Double duyarlık kaybıyla ilgili olduğunu unutmayın. Örnekte gösterildiği gibi , ve değerleri değerlere dönüştürülürken Decimal Int64 duyarlık UInt64 kaybı Double mümkündür.
Bir değerin başka bir temel sayısal veri türünün değerine dönüştürmesi bir daraltma dönüştürmesidir ve bir tür dönüştürme işleci (C#), dönüştürme yöntemi (Visual Basic) veya yöntem çağrısı Double Convert gerektirir. Hedef veri türünün ve özellikleri tarafından tanımlanan hedef veri türünün aralığının dışındaki değerler aşağıdaki tabloda gösterildiği gibi MinValue
MaxValue
davranır.
Hedef tür | Sonuç |
---|---|
Herhangi bir tamsayı türü | Dönüştürmenin OverflowException denetlenen bir bağlamda gerçekleşmesi özel durumdur. Dönüştürme denetlenmeyen bir bağlamda (C# içinde varsayılan) gerçekleşirse, dönüştürme işlemi başarılı olur ancak değer taşması olur. |
Decimal | Özel OverflowException durum. |
Single | Single.NegativeInfinity negatif değerler için. Single.PositiveInfinity pozitif değerler için. |
Buna ek olarak, , ve işaretli bir bağlamda tamsayılara dönüştürmeler için bir oluşturur, ancak denetlenmeyen bağlamda tamsayılara dönüştürlendiğinde bu değerler Double.NaN Double.PositiveInfinity Double.NegativeInfinity OverflowException taşma gösterir. dönüştürmeleri için Decimal her zaman bir OverflowException atarlar. dönüştürmeleri için Single sırasıyla Single.NaN , Single.PositiveInfinity ve Single.NegativeInfinity 'ye dönüştürürler.
Duyarlık kaybının bir değeri başka bir sayısal Double türe dönüştürmeye neden olduğunu unutmayın. Örnekteki çıktıda da olduğu gibi tamsayı türlerinden herhangi birına dönüştürme durumunda, değer yuvarlanmış (Visual Basic gibi) veya kesilmiş (C# gibi) kesirli bileşen Double kaybolur. ve değerlerine Decimal Single dönüştürmeler için Double değerin hedef veri türünde kesin bir temsili olabilir.
Aşağıdaki örnek, bir dizi değeri diğer Double birkaç sayısal türe dönüştürür. Dönüştürmeler, Visual Basic (varsayılan) ve C# içinde (işaretli anahtar sözcük nedeniyle) denetlenen bağlamda gerçekleşir. Örnekten elde edilen çıktı, denetlenmeyen bir bağlamda her ikisinde de dönüştürmelerin sonucu gösterir. Derleyici anahtarıyla derleme ve C# içinde deyimini açıklama Visual Basic denetlenmeyen bir bağlamda /removeintchecks+
dönüştürmeler checked
gerçekleştirin.
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)
Sayısal türlerin dönüştürmesi hakkında daha fazla bilgi için, bkz. .NET Framework tür dönüştürme ve Tür Dönüştürme Tabloları.
Kayan Nokta İşlevleri
Yapı Double ve ilgili türler, aşağıdaki alanlarda işlem gerçekleştirme yöntemleri sağlar:
değerlerinin karşılaştırması. İki değerin eşit olup olmadığını belirlemek için yöntemini veya iki değer arasındaki ilişkiyi Equals Double belirlemek için yöntemini CompareTo çağırebilirsiniz.
Yapı Double ayrıca eksiksiz bir karşılaştırma işleçleri kümesi de destekler. Örneğin, eşitlik veya eşitsizlik için test veya bir değerin başka bir değerden büyük veya başka bir değere eşit olup olmadığını belirleme. İşlecilerden biri dışında bir sayısal Double türse, karşılaştırmayı gerçekleştirmeden Double önce bir'e dönüştürülür.
Uyarı
Duyarlık farklılıkları nedeniyle, eşit olmasını beklediğiniz iki değerin eşit olmayan olduğu ortaya çıkar ve bu da Double karşılaştırmanın sonucu etkiler. İki değeri karşılaştırma hakkında daha fazla bilgi için Eşitlik Testi bölümüne Double bakın.
Bu özel değerleri test IsNaN etmek için , , ve yöntemlerini de IsInfinity IsPositiveInfinity IsNegativeInfinity çağırarak.
Matematik işlemleri. Toplama, çıkarma, çarpma ve bölme gibi yaygın aritmetik işlemler, yöntemler yerine dil derleyicileri ve Ortak Ara Dil (CIL) yönergeleri Double tarafından uygulanır. Matematiksel işlemdeki işlenenlerden biri dışında bir sayısal türse, işlemi gerçekleştirmeden önce Double Double bir türüne dönüştürülür. İşlem sonucu da bir Double değerdir.
Diğer matematik işlemleri,
static
sınıfındaki (Shared
Visual Basic) yöntemleri çağrılarak System.Math yapılabilir. Aritmetik (, ve gibi), geometri (ve gibi) ve matematik (gibi) için yaygın olarak kullanılan ek yöntemleri Math.Abs Math.Sign Math.Sqrt Math.Cos Math.Sin Math.Log içerir.Ayrıca bir değerde tek tek bitleri de Double işleysiniz. yöntemi BitConverter.DoubleToInt64Bits bir Double değerin bit desenini 64 bit tamsayıda korur. yöntemi BitConverter.GetBytes(Double) bit desenini bir byte dizisinde döndürür.
yuvarlama. Yuvarlama genellikle kayan nokta gösterimi ve duyarlık sorunlarının neden olduğu değerler arasındaki farkların etkisini azaltmak için bir teknik olarak kullanılır. yöntemini çağırarak Double bir değeri Math.Round yuvarlayebilirsiniz.
Biçimlendirme. yöntemini çağırarak Double veya bileşik biçimlendirme özelliğini kullanarak bir değeri dize ToString gösterimine dönüştürebilirsiniz. Biçim dizelerinin kayan nokta değerlerinin dize gösterimini denetlemesi hakkında bilgi için Standart Sayısal Biçim Dizeleri ve Özel Sayısal Biçim Dizeleri konularına bakın.
Dizeleri ayrıştırma. bir kayan nokta değerinin dize gösterimini veya yöntemini Double çağırarak bir değere Parse TryParse dönüştürebilirsiniz. Ayrıştırma işlemi başarısız olursa yöntemi Parse bir özel durum oluştururken yöntemi TryParse
false
döndürür.Tür dönüştürme. Yapısı, arabirim için iki standart veri türü arasında dönüştürmeyi destekleyen Double açık bir arabirim .NET Framework IConvertible sağlar. Dil derleyicileri, diğer tüm standart sayısal türlerin değerlerinin değerlere örtülü olarak dönüştürme işlemini de Double destekler. Herhangi bir standart sayısal türün değerinin bir değerine dönüştürmesi bir genişletilen dönüştürmedir ve bir tür dönüştürme işlecinin veya dönüştürme yönteminin Double kullanıcısı gerektirmez,
Ancak, ve Int64 Single değerlerinin dönüştürmesi bir duyarlık kaybı olabilir. Aşağıdaki tabloda bu türlerin her biri için duyarlık farklılıkları listelemektedir:
Tür En yüksek duyarlık İç duyarlık Double 15 17 Int64 19 ondalık basamak 19 ondalık basamak Single 7 ondalık basamak 9 ondalık basamak Duyarlık sorunu en sık, Single değerlere dönüştürülen değerleri Double etkiler. Aşağıdaki örnekte, aynı bölme işlemleri tarafından üretilen iki değer eşit değildir çünkü değerlerden biri değerine dönüştürülen tek duyarlıklı kayan nokta Double değeridir.
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
Alanlar
Epsilon |
Sıfırdan büyük olan Double en küçük pozitif değeri temsil eder. Bu alan sabittir. |
MaxValue |
Bir değerinin mümkün olan en büyük değerini temsil Double eder. Bu alan sabittir. |
MinValue |
bir değerinin mümkün olan en küçük değerini temsil Double eder. Bu alan sabittir. |
NaN |
Sayı ( ) değil, bir değeri temsil |
NegativeInfinity |
Negatif sonsuzluğu temsil eder. Bu alan sabittir. |
PositiveInfinity |
Pozitif sonsuzluğu temsil eder. Bu alan sabittir. |
Yöntemler
CompareTo(Double) |
Bu örneği belirtilen çift duyarlıklı kayan nokta sayısıyla karşılar ve bu örneğin değerinin belirtilen çift duyarlıklı kayan nokta sayısından küçük, eşit veya daha büyük olup olmadığını belirten bir tamsayı döndürür. |
CompareTo(Object) |
Bu örneği belirtilen bir nesneyle karşılar ve bu örneğin değerinin belirtilen nesnenin değerinden küçük, eşit veya daha büyük olduğunu belirten bir tamsayı döndürür. |
Equals(Double) |
Bu örnekle belirtilen bir nesnenin aynı değeri temsil edip Double etmey olmadığını belirten bir değer döndürür. |
Equals(Object) |
Bu örneğin, belirtilen bir nesneye eşit olup olmadığını gösteren bir değeri döndürür. |
GetHashCode() |
Bu örneğe ilişkin karma kodu döndürür. |
GetTypeCode() | |
IsFinite(Double) |
Belirtilen değerin sınırlı (sıfır, normal veya normal) olup olmadığını belirler. |
IsInfinity(Double) |
Belirtilen say ın negatif mi yoksa pozitif sonsuz mu olduğunu gösteren bir değer döndürür. |
IsNaN(Double) |
Belirtilen değerin sayı ( ) olup olmadığını belirten bir değer NaN döndürür. |
IsNegative(Double) |
Belirtilen değerin negatif olup olmadığını belirler. |
IsNegativeInfinity(Double) |
Belirtilen say ın negatif sonsuz olarak değerlendirilip değerlendirilmeyildiğini belirten bir değer döndürür. |
IsNormal(Double) |
Belirtilen değerin normal olup olmadığını belirler. |
IsPositiveInfinity(Double) |
Belirtilen say ın pozitif sonsuz olarak değerlendirilip değerlendirilmeyildiğini belirten bir değer döndürür. |
IsSubnormal(Double) |
Belirtilen değerin normalin altında olup olmadığını belirler. |
Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider) |
Belirtilen bir stildeki bir sayının dize gösterimini ve kültüre özgü biçimlendirmeyi çift duyarlıklı kayan noktalı sayı eşdeğerine dönüştürür. |
Parse(String) |
Bir sayının size gösterimini çift duyarlıklı kayan noktalı sayı eşdeğerine dönüştürür. |
Parse(String, IFormatProvider) |
Belirli bir kültüre özgü biçimdeki bir sayının dize gösterimini çift duyarlıklı kayan noktalı sayı eşdeğerine dönüştürür. |
Parse(String, NumberStyles) |
Belirtilen stilde bir sayın dize gösterimini çift duyarlıklı kayan nokta sayı eşdeğere dönüştürür. |
Parse(String, NumberStyles, IFormatProvider) |
Belirtilen bir stil ve kültüre özgü biçimdeki bir sayının dize gösterimini çift duyarlıklı kayan noktalı sayı eşdeğerine dönüştürür. |
ToString() |
Bu örneğin sayısal değerini eşdeğer dize gösterimine dönüştürür. |
ToString(IFormatProvider) |
Bu örneğin sayısal değerini belirtilen kültüre özgü biçim bilgilerini kullanarak eşdeğer dize gösterimine dönüştürür. |
ToString(String) |
Bu örneğin sayısal değerini, belirtilen biçimi kullanarak eşdeğer dize gösterimine dönüştürür. |
ToString(String, IFormatProvider) |
Bu örneğin sayısal değerini belirtilen biçim ve kültüre özgü biçim bilgilerini kullanarak eşdeğer dize gösterimine dönüştürür. |
TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider) |
Geçerli çift örneğin değerini sağlanan karakter aralığına biçimlendirmeye çalışır. |
TryParse(ReadOnlySpan<Char>, Double) |
Belirtilen stilde ve kültüre özgü biçimdeki bir sayın span gösterimini çift duyarlıklı kayan nokta sayısı eşdeğere dönüştürür. Dönüştürmenin başarılı veya başarısız olduğunu gösteren dönüş değeri. |
TryParse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider, Double) |
Belirtilen stilde ve kültüre özgü biçimdeki bir sayın dize gösterimini içeren bir karakter yayma noktasını çift duyarlıklı kayan nokta sayı eşdeğeri olarak dönüştürür. Dönüştürmenin başarılı veya başarısız olduğunu gösteren dönüş değeri. |
TryParse(String, Double) |
Bir sayının size gösterimini çift duyarlıklı kayan noktalı sayı eşdeğerine dönüştürür. Dönüştürmenin başarılı veya başarısız olduğunu gösteren dönüş değeri. |
TryParse(String, NumberStyles, IFormatProvider, Double) |
Belirtilen bir stil ve kültüre özgü biçimdeki bir sayının dize gösterimini çift duyarlıklı kayan noktalı sayı eşdeğerine dönüştürür. Dönüştürmenin başarılı veya başarısız olduğunu gösteren dönüş değeri. |
İşleçler
Equality(Double, Double) |
Belirtilen iki değerin eşit olup olmadığını Double belirten bir değer döndürür. |
GreaterThan(Double, Double) |
Belirtilen değerin başka bir belirtilen Double değerden büyük olup olmadığını belirten bir değer Double döndürür. |
GreaterThanOrEqual(Double, Double) |
Belirtilen değerin belirtilen başka bir değerden Double büyük veya başka bir değere eşit olup olmadığını belirten bir değer Double döndürür. |
Inequality(Double, Double) |
Belirtilen iki değerin eşit olup olmadığını Double belirten bir değer döndürür. |
LessThan(Double, Double) |
Belirtilen değerin başka bir belirtilen Double değerden küçük olup olmadığını belirten bir değer Double döndürür. |
LessThanOrEqual(Double, Double) |
Belirtilen değerin belirtilen başka bir değerden Double küçük veya başka bir değere eşit olup olmadığını belirten bir değer Double döndürür. |
Belirtik Arabirim Kullanımları
Şunlara uygulanır
İş Parçacığı Güvenliği
Bu türün tüm üyeleri iş parçacığı güvenlidir. Örneğin durumunu değiştirmek için görüntülenen üyeler, gerçekte yeni değer ile başlatılan yeni bir örneği döndürür. Diğer türlerde olduğu gibi, bu türün örneğini içeren paylaşılan değişkenini okuma ve yazma, iş parçacığı güvenliğini sağlamak için bir kilit tarafından korunmalıdır.