System.Single Structure

Represents a single-precision floating-point number.

See Also: Single Members

Syntax

[System.Runtime.InteropServices.ComVisible(true)]
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable

Remarks

The float value type represents a single-precision 32-bit number with values ranging from negative 3.402823e38 to positive 3.402823e38, as well as positive or negative zero, float.PositiveInfinity, float.NegativeInfinity, and not a number (float.NaN). 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 float type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.

This topic consists of the following sections:

float provides methods to compare instances of this type, to convert the value of an instance to its string representation, and to convert the string representation of a number to an instance of this type. For information about how format specification codes control the string representation of value types, see Formatting Types, Standard Numeric Format Strings, and Custom Numeric Format Strings.

Floating-point representation and precision

The float data type stores single-precision floating-point values in a 32-bit binary format, as shown in the following table:

Significand or mantissa

0-22

Exponent

23-30

Sign (0 = positive, 1 = negative)

31

Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or Math.PI), binary fractions are unable to represent some fractional values. For example, 2/10, which is represented precisely by .2 as a decimal fraction, is represented by .0011111001001100 as a binary fraction, with the pattern "1100" 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 increases its lack of precision. For example, if you compare the results of multiplying .3 by 10 and adding .3 to .3 nine times, you will see that addition produces the less precise result, because it involves eight more operations than multiplication. Note that this disparity is apparent only if you display the two float values by using the "R" standard numeric format string, which, if necessary, displays all 9 digits of precision supported by the float type.

code reference: System.Single.Structure#3

Because some numbers cannot be represented exactly as fractional binary values, floating-point numbers can only approximate real numbers.

All floating-point numbers have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. A float value has up to 7 decimal digits of precision, although a maximum of 9 digits is maintained internally. This means that some floating-point operations may lack the precision to change a floating-point value. The following example defines a large single-precision floating-point value, and then adds the product of float.Epsilon and one quadrillion to it. However, the product 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 1.

code reference: System.Single.Structure#4

The limited precision of a floating-point number has several consequences:

Testing for equality

To be considered equal, two float values must represent identical values. However, because of differences in precision between values, or because of a loss of precision by one or both values, floating-point values that are expected to be identical often turn out to be unequal due to differences in their least significant digits. As a result, calls to the float.Equals(float) method to determine whether two values are equal, or calls to the float.CompareTo(float) method to determine the relationship between two float values, often yield unexpected results. This is evident in the following example, where two apparently equal float values turn out to be unequal, because the first value has 7 digits of precision, whereas the second value has 9.

code reference: System.Single.Structure#9

Calculated values that follow different code paths and that are manipulated in different ways often prove to be unequal. In the following example, one float value is squared, and then the square root is calculated to restore the original value. A second float 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 float.Equals(float) 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 float value shows that the second value is .0000000000001 less than the first.

code reference: System.Single.Structure#10

In cases where a loss of precision is likely to affect the result of a comparison, you can use the following techniques instead of calling the float.Equals(float) or float.CompareTo(float) method:

Floating-point values and exceptions

Operations with floating-point values do not throw exceptions, unlike operations with integral types, which throw exceptions in cases of illegal operations such as division by zero or overflow. Instead, in these situations, the result of a floating-point operation is zero, positive infinity, negative infinity, or not a number (NaN):

Floating-point functionality

The float structure and related types provide methods to perform the following categories of operations:

Thread Safety

All public static members of this type are safe for multithreaded operations. No instance members are guaranteed to be thread safe.

Requirements

Namespace: System
Assembly: mscorlib (in mscorlib.dll)
Assembly Versions: 1.0.5000.0, 2.0.0.0, 4.0.0.0