diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison1.cs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison1.cs index b3e50e1a74b65..39c0d36f90011 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison1.cs +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison1.cs @@ -7,7 +7,7 @@ public static void Main() { double value1 = .333333333333333; double value2 = 1.0/3; - Console.WriteLine($"{value1:R} = {value2:R}: {value1.Equals(value2)}"); + Console.WriteLine($"{value1} = {value2}: {value1.Equals(value2)}"); } } // The example displays the following output: diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison2.cs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison2.cs deleted file mode 100644 index e856e479137a7..0000000000000 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison2.cs +++ /dev/null @@ -1,20 +0,0 @@ -// -using System; - -public class Example1 -{ - 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($"{value1} = {value2}: {value1.Equals(value2)}{Environment.NewLine}"); - Console.WriteLine($"{value1:R} = {value2:R}"); - } -} -// The example displays the following output: -// 100.10142 = 100.10142: False -// -// 100.10142 = 100.10141999999999 -// diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison3.cs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison3.cs index 5e18d90ba6034..2c548a3ae9862 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison3.cs +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison3.cs @@ -1,18 +1,19 @@ -// using System; public class Example2 { 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($"{value1:R} = {value2:R}: {value1.Equals(value2)}"); + Console.WriteLine($"{value1} = {value2}: {value1.Equals(value2)}"); + + // The example displays the following output: + // 0.3333333 = 0.3333333: True + // } } -// The example displays the following output: -// 0.3333333 = 0.3333333: True -// diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison4.cs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison4.cs index a652380e23253..577ba93083fcd 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison4.cs +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/csharp/comparison4.cs @@ -10,8 +10,8 @@ public static void Main() for (int ctr = 1; ctr <= 10; ctr++) one2 += .1; - Console.WriteLine($"{one1:R} = {one2:R}: {one1.Equals(one2)}"); - Console.WriteLine($"{one1:R} is approximately equal to {one2:R}: {IsApproximatelyEqual(one1, one2, .000000001)}"); + Console.WriteLine($"{one1} = {one2}: {one1.Equals(one2)}"); + Console.WriteLine($"{one1} is approximately equal to {one2}: {IsApproximatelyEqual(one1, one2, .000000001)}"); } static bool IsApproximatelyEqual(double value1, double value2, double epsilon) @@ -34,6 +34,7 @@ static bool IsApproximatelyEqual(double value1, double value2, double epsilon) 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 diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/Project.fsproj b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/Project.fsproj new file mode 100644 index 0000000000000..3154099aec4ec --- /dev/null +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/Project.fsproj @@ -0,0 +1,25 @@ + + + + Library + net10.0 + + + + + + + + + + + + + + + + + + + + diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison1.fs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison1.fs index 85b789cc0b7d2..579c3a34cb217 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison1.fs +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison1.fs @@ -5,7 +5,8 @@ open System let value1 = 0.333333333333333 let value2 = 1. / 3. -printfn $"{value1:R} = {value2:R}: {value1.Equals value2}" +printfn $"{value1} = {value2}: {value1.Equals value2}" + // The example displays the following output: // 0.333333333333333 = 0.33333333333333331: False -// \ No newline at end of file +// diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison2.fs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison2.fs deleted file mode 100644 index 0a98d9b10f777..0000000000000 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison2.fs +++ /dev/null @@ -1,20 +0,0 @@ -module comparison2 - -// -open System - -let value1 = - Math.Pow(100.10142, 2) - |> sqrt - -let value2 = - let v = pown (value1 * 3.51) 2 - (Math.Sqrt v) / 3.51 - -printfn $"{value1} = {value2}: {value1.Equals value2}\n" -printfn $"{value1:R} = {value2:R}" -// The example displays the following output: -// 100.10142 = 100.10142: False -// -// 100.10142 = 100.10141999999999 -// \ No newline at end of file diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison3.fs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison3.fs index d494d27c380e7..8c58cd01d1738 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison3.fs +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison3.fs @@ -8,7 +8,8 @@ let v2 = 1. / 3. let precision = 7 let value1 = Math.Round(v1, precision) let value2 = Math.Round(v2, precision) -printfn $"{value1:R} = {value2:R}: {value1.Equals value2}" +printfn $"{value1} = {value2}: {value1.Equals value2}" + // The example displays the following output: // 0.3333333 = 0.3333333: True -// \ No newline at end of file +// diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison4.fs b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison4.fs index 64b90f722b865..29502a935a89e 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison4.fs +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/fsharp/comparison4.fs @@ -5,21 +5,21 @@ open System let isApproximatelyEqual (value1: double) (value2: double) (epsilon: double) = // If they are equal anyway, just return True. - if value1.Equals value2 then + if value1.Equals value2 then true else // Handle NaN, Infinity. - if Double.IsInfinity value1 || Double.IsNaN value1 then + if Double.IsInfinity value1 || Double.IsNaN value1 then value1.Equals value2 elif Double.IsInfinity value2 || Double.IsNaN value2 then value1.Equals value2 else // Handle zero to avoid division by zero let divisor = max value1 value2 - let divisor = + let divisor = if divisor.Equals 0 then min value1 value2 - else + else divisor abs ((value1 - value2) / divisor) <= epsilon @@ -28,10 +28,10 @@ let mutable one2 = 0. for _ = 1 to 10 do one2 <- one2 + 0.1 -printfn $"{one1:R} = {one2:R}: {one1.Equals one2}" -printfn $"{one1:R} is approximately equal to {one2:R}: {isApproximatelyEqual one1 one2 0.000000001}" +printfn $"{one1} = {one2}: {one1.Equals one2}" +printfn $"{one1} is approximately equal to {one2}: {isApproximatelyEqual one1 one2 0.000000001}" // The example displays the following output: // 1 = 0.99999999999999989: False // 1 is approximately equal to 0.99999999999999989: True -// \ No newline at end of file +// diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison1.vb b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison1.vb index 2fea6776f718e..99826e6fd34cd 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison1.vb +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison1.vb @@ -6,9 +6,10 @@ Module Example1 Public Sub Main() Dim value1 As Double = 0.333333333333333 Dim value2 As Double = 1 / 3 - Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2)) + Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2)) End Sub End Module + ' The example displays the following output: ' 0.333333333333333 = 0.33333333333333331: False ' diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison2.vb b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison2.vb deleted file mode 100644 index 2db46fcd00c11..0000000000000 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison2.vb +++ /dev/null @@ -1,21 +0,0 @@ -' Visual Basic .NET Document -Option Strict On - -' -Module Example2 - 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 -' diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison3.vb b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison3.vb index c90fc1c916868..3060e3e01d7e9 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison3.vb +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison3.vb @@ -9,9 +9,10 @@ Module Example3 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)) + Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2)) End Sub End Module + ' The example displays the following output: ' 0.3333333 = 0.3333333: True ' diff --git a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison4.vb b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison4.vb index 5c646a62acf21..67a96bacfc517 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison4.vb +++ b/docs/fundamentals/runtime-libraries/snippets/System/Double/Overview/vb/comparison4.vb @@ -9,8 +9,8 @@ Module Example4 For ctr As Integer = 1 To 10 one2 += 0.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}", + Console.WriteLine("{0} = {1}: {2}", one1, one2, one1.Equals(one2)) + Console.WriteLine("{0} is approximately equal to {1}: {2}", one1, one2, IsApproximatelyEqual(one1, one2, 0.000000001)) End Sub @@ -36,6 +36,7 @@ Module Example4 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 diff --git a/docs/fundamentals/runtime-libraries/system-double.md b/docs/fundamentals/runtime-libraries/system-double.md index e69370b89961d..59e6028276f43 100644 --- a/docs/fundamentals/runtime-libraries/system-double.md +++ b/docs/fundamentals/runtime-libraries/system-double.md @@ -1,7 +1,7 @@ --- title: System.Double struct description: Learn about the System.Double struct. -ms.date: 02/21/2025 +ms.date: 04/07/2026 dev_langs: - CSharp - FSharp @@ -11,7 +11,7 @@ dev_langs: [!INCLUDE [context](includes/context.md)] -The value type represents a double-precision 64-bit number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, , , and not a number (). It is intended to represent values that are extremely large (such as distances between planets or galaxies) or extremely small (such as the molecular mass of a substance in kilograms) and that often are imprecise (such as the distance from earth to another solar system). The type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic. +The value type represents a double-precision 64-bit number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, , , and not a number (). It's intended to represent values that are extremely large (such as distances between planets or galaxies) or extremely small (such as the molecular mass of a substance in kilograms) and that often are imprecise (such as the distance from earth to another solar system). The type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic. ## Floating-point representation and precision @@ -23,15 +23,15 @@ The data type stores double-precision floating-point values | Exponent | 52-62 | | Sign (0 = Positive, 1 = Negative) | 63 | -Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or ), binary fractions are unable to represent some fractional values. For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity. In this case, the floating-point value provides an imprecise representation of the number that it represents. Performing additional mathematical operations on the original floating-point value often tends to increase its lack of precision. For example, if we compare the result of multiplying .1 by 10 and adding .1 to .1 nine times, we see that addition, because it has involved eight more operations, has produced the less precise result. Note that this disparity is apparent only if we display the two values by using the "R" [standard numeric format string](../../standard/base-types/standard-numeric-format-strings.md), which if necessary displays all 17 digits of precision supported by the type. +Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or ), binary fractions are unable to represent some fractional values. For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity. In this case, the floating-point value provides an imprecise representation of the number that it represents. Performing additional mathematical operations on the original floating-point value often tends to increase its lack of precision. For example, if you compare the result of multiplying .1 by 10 and adding .1 to .1 nine times, you see that addition, because it has involved eight more operations, has produced the less precise result. (Prior to .NET 10, this disparity is apparent only if you display the two values by using the "R" [standard numeric format string](../../standard/base-types/standard-numeric-format-strings.md), which displays up to all 17 digits of precision supported by the type.) :::code language="csharp" source="./snippets/System/Double/Overview/csharp/representation1.cs" id="Snippet3"::: :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/representation1.fs" id="Snippet3"::: :::code language="vb" source="./snippets/System/Double/Overview/vb/representation1.vb" id="Snippet3"::: -Because some numbers cannot be represented exactly as fractional binary values, floating-point numbers can only approximate real numbers. +Because some numbers can't be represented exactly as fractional binary values, floating-point numbers can only approximate real numbers. -All floating-point numbers also have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. A value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally. This means that some floating-point operations may lack the precision to change a floating point value. The following example provides an illustration. It defines a very large floating-point value, and then adds the product of and one quadrillion to it. The product, however, is too small to modify the original floating-point value. Its least significant digit is thousandths, whereas the most significant digit in the product is 10-309. +All floating-point numbers also have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. A value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally. This means that some floating-point operations might lack the precision to change a floating point value. The following example provides an illustration. It defines a very large floating-point value, and then adds the product of and one quadrillion to it. The product, however, is too small to modify the original floating-point value. Its least significant digit is thousandths, whereas the most significant digit in the product is 10-309. :::code language="csharp" source="./snippets/System/Double/Overview/csharp/representation2.cs" id="Snippet4"::: :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/representation2.fs" id="Snippet4"::: @@ -39,17 +39,17 @@ All floating-point numbers also have a limited number of significant digits, whi The limited precision of a floating-point number has several consequences: -- Two floating-point numbers that appear equal for a particular precision might not compare equal because their least significant digits are different. In the following example, a series of numbers are added together, and their total is compared with their expected total. Although the two values appear to be the same, a call to the `Equals` method indicates that they are not. +- Two floating-point numbers that appear equal for a particular precision might not compare equal, because their least significant digits are different. In the following example, a series of numbers are added together, and their total is compared with their expected total. :::code language="csharp" source="./snippets/System/Double/Overview/csharp/precisionlist3.cs" id="Snippet6"::: :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/precisionlist3.fs" id="Snippet6"::: :::code language="vb" source="./snippets/System/Double/Overview/vb/precisionlist3.vb" id="Snippet6"::: - If you change the format items in the statement from `{0}` and `{1}` to `{0:R}` and `{1:R}` to display all significant digits of the two values, it is clear that the two values are unequal because of a loss of precision during the addition operations. In this case, the issue can be resolved by calling the method to round the values to the desired precision before performing the comparison. + The two values are unequal because of a loss of precision during the addition operations. In this case, the issue can be resolved by calling the method to round the values to the desired precision before performing the comparison. - A mathematical or comparison operation that uses a floating-point number might not yield the same result if a decimal number is used, because the binary floating-point number might not equal the decimal number. A previous example illustrated this by displaying the result of multiplying .1 by 10 and adding .1 times. - When accuracy in numeric operations with fractional values is important, you can use the rather than the type. When accuracy in numeric operations with integral values beyond the range of the types is important, use the type. + When accuracy in numeric operations with fractional values is important, you can use the type rather than the type. When accuracy in numeric operations with integral values beyond the range of the types is important, use the type. - A value might not *round-trip* if a floating-point number is involved. A value is said to round-trip if an operation converts an original floating-point number to another form, an inverse operation transforms the converted form back to a floating-point number, and the final floating-point number is equal to the original floating-point number. The round trip might fail because one or more least significant digits are lost or changed in the conversion. @@ -61,7 +61,7 @@ The limited precision of a floating-point number has several consequences: If you're targeting .NET Framework, the values can be successfully round-tripped by using the "G17" [standard numeric format string](../../standard/base-types/standard-numeric-format-strings.md) to preserve the full precision of values. -- values have less precision than values. A value that is converted to a seemingly equivalent often does not equal the value because of differences in precision. In the following example, the result of identical division operations is assigned to a and a value. After the value is cast to a , a comparison of the two values shows that they are unequal. +- values have less precision than values. A value that's converted to a seemingly equivalent often does not equal the value because of differences in precision. In the following example, the result of identical division operations is assigned to a and a value. After the value is cast to a , a comparison of the two values shows that they are unequal. :::code language="csharp" source="./snippets/System/Double/Overview/csharp/precisionlist1.cs" id="Snippet5"::: :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/precisionlist1.fs" id="Snippet5"::: @@ -69,7 +69,7 @@ The limited precision of a floating-point number has several consequences: To avoid this problem, use either the in place of the data type, or use the method so that both values have the same precision. -In addition, the result of arithmetic and assignment operations with values may differ slightly by platform because of the loss of precision of the type. For example, the result of assigning a literal value may differ in the 32-bit and 64-bit versions of .NET. The following example illustrates this difference when the literal value -4.42330604244772E-305 and a variable whose value is -4.42330604244772E-305 are assigned to a variable. Note that the result of the method in this case does not suffer from a loss of precision. +In addition, the result of arithmetic and assignment operations with values might differ slightly by platform because of the loss of precision of the type. For example, the result of assigning a literal value might differ in the 32-bit and 64-bit versions of .NET. The following example illustrates this difference when the literal value -4.42330604244772E-305 and a variable whose value is -4.42330604244772E-305 are assigned to a variable. Note that the result of the method in this case does not suffer from a loss of precision. :::code language="csharp" source="./snippets/System/Double/Overview/csharp/precision1.cs" id="Snippet1"::: :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/precision1.fs" id="Snippet1"::: @@ -83,12 +83,6 @@ To be considered equal, two values must represent identical :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/comparison1.fs" id="Snippet9"::: :::code language="vb" source="./snippets/System/Double/Overview/vb/comparison1.vb" id="Snippet9"::: -Calculated values that follow different code paths and that are manipulated in different ways often prove to be unequal. In the following example, one value is squared, and then the square root is calculated to restore the original value. A second is multiplied by 3.51 and squared before the square root of the result is divided by 3.51 to restore the original value. Although the two values appear to be identical, a call to the method indicates that they are not equal. Using the "R" standard format string to return a result string that displays all the significant digits of each Double value shows that the second value is .0000000000001 less than the first. - -:::code language="csharp" source="./snippets/System/Double/Overview/csharp/comparison2.cs" id="Snippet10"::: -:::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/comparison2.fs" id="Snippet10"::: -:::code language="vb" source="./snippets/System/Double/Overview/vb/comparison2.vb" id="Snippet10"::: - In cases where a loss of precision is likely to affect the result of a comparison, you can adopt any of the following alternatives to calling the or method: - Call the method to ensure that both values have the same precision. The following example modifies a previous example to use this approach so that two fractional values are equivalent. @@ -104,7 +98,7 @@ In cases where a loss of precision is likely to affect the result of a compariso > [!WARNING] > is sometimes used as an absolute measure of the distance between two values when testing for equality. However, measures the smallest possible value that can be added to, or subtracted from, a whose value is zero. For most positive and negative values, the value of is too small to be detected. Therefore, except for values that are zero, we do not recommend its use in tests for equality. - The following example uses the latter approach to define an `IsApproximatelyEqual` method that tests the relative difference between two values. It also contrasts the result of calls to the `IsApproximatelyEqual` method and the method. + The following example uses the latter approach to define an `IsApproximatelyEqual` method that tests the relative difference between two values. The method divides by `Math.Max(value1, value2)` so the comparison is relative to the larger (by magnitude) of the two values, which places the result in the correct order of magnitude. If `Math.Max` returns zero (which happens when one value is zero and the other is negative), the method falls back to `Math.Min(value1, value2)` to use the non-zero value as the divisor. It also contrasts the result of calls to the `IsApproximatelyEqual` method and the method. :::code language="csharp" source="./snippets/System/Double/Overview/csharp/comparison4.cs" id="Snippet12"::: :::code language="fsharp" source="./snippets/System/Double/Overview/fsharp/comparison4.fs" id="Snippet12"::: @@ -112,7 +106,7 @@ In cases where a loss of precision is likely to affect the result of a compariso ## Floating-point values and exceptions -Unlike operations with integral types, which throw exceptions in cases of overflow or illegal operations such as division by zero, operations with floating-point values do not throw exceptions. Instead, in exceptional situations, the result of a floating-point operation is zero, positive infinity, negative infinity, or not a number (NaN): +Unlike operations with integral types, which throw a for division by zero or an for overflow in a [checked context](../../csharp/language-reference/statements/checked-and-unchecked.md), operations with floating-point values don't throw exceptions. Instead, in exceptional situations, the result of a floating-point operation is zero, positive infinity, negative infinity, or not a number (NaN): - If the result of a floating-point operation is too small for the destination format, the result is zero. This can occur when two very small numbers are multiplied, as the following example shows. @@ -160,7 +154,7 @@ The conversion of a value to a value of any other primitive In addition, , , and throw an for conversions to integers in a checked context, but these values overflow when converted to integers in an unchecked context. For conversions to , they always throw an . For conversions to , they convert to , , and , respectively. -A loss of precision may result from converting a value to another numeric type. In the case of converting to any of the integral types, as the output from the example shows, the fractional component is lost when the value is either rounded (as in Visual Basic) or truncated (as in C#). For conversions to and values, the value may not have a precise representation in the target data type. +A loss of precision might result from converting a value to another numeric type. In the case of converting to any of the integral types, as the output from the example shows, the fractional component is lost when the value is either rounded (as in Visual Basic) or truncated (as in C#). For conversions to and values, the value might not have a precise representation in the target data type. The following example converts a number of values to several other numeric types. The conversions occur in a checked context in Visual Basic (the default), in C# (because of the [checked](/dotnet/csharp/language-reference/keywords/checked) keyword), and in F# (because of the [Checked](https://fsharp.github.io/fsharp-core-docs/reference/fsharp-core-operators-checked.html) module). The output from the example shows the result for conversions in both a checked an unchecked context. You can perform conversions in an unchecked context in Visual Basic by compiling with the `/removeintchecks+` compiler switch, in C# by commenting out the `checked` statement, and in F# by commenting out the `open Checked` statement. @@ -179,11 +173,11 @@ The structure and related types provide methods to perform The structure also supports a complete set of comparison operators. For example, you can test for equality or inequality, or determine whether one value is greater than or equal to another. If one of the operands is a numeric type other than a , it is converted to a before performing the comparison. > [!WARNING] - > Because of differences in precision, two values that you expect to be equal may turn out to be unequal, which affects the result of the comparison. See the [Test for equality](#test-for-equality) section for more information about comparing two values. + > Because of differences in precision, two values that you expect to be equal might turn out to be unequal, which affects the result of the comparison. For information about comparing two values, see the [Test for equality](#test-for-equality) section. You can also call the , , , and methods to test for these special values. -- **Mathematical operations**. Common arithmetic operations, such as addition, subtraction, multiplication, and division, are implemented by language compilers and Common Intermediate Language (CIL) instructions, rather than by methods. If one of the operands in a mathematical operation is a numeric type other than a , it is converted to a before performing the operation. The result of the operation is also a value. +- **Mathematical operations**. Common arithmetic operations, such as addition, subtraction, multiplication, and division, are implemented by language compilers and Common Intermediate Language (CIL) instructions, rather than by methods. If one of the operands in a mathematical operation is a numeric type other than a , it's converted to a before performing the operation. The result of the operation is also a value. Other mathematical operations can be performed by calling `static` (`Shared` in Visual Basic) methods in the class. It includes additional methods commonly used for arithmetic (such as , , and ), geometry (such as and ), and calculus (such as ).