本文由机器翻译。若要查看英语原文,请勾选“英语”复选框。 也可将鼠标指针移到文本上,在弹出窗口中显示英语原文。
翻译
英语

Single 结构

 

表示一个单精度浮点数。

命名空间:   System
程序集:  mscorlib(位于 mscorlib.dll)

[SerializableAttribute]
[ComVisibleAttribute(true)]
public struct Single : IComparable, IFormattable, IConvertible, 
	IComparable<float>, IEquatable<float>

名称说明
System_CAPS_pubmethodCompareTo(Object)

将此实例与指定对象进行比较,并返回一个整数,该整数指示此实例的值是小于、等于还是大于指定对象的值。

System_CAPS_pubmethodCompareTo(Single)

将此实例与指定的单精度浮点数进行比较,并返回一个整数,该整数指示此实例的值是小于、等于还是大于指定单精度浮点数的值。

System_CAPS_pubmethodEquals(Object)

返回一个值,该值指示此实例是否等于指定的对象。(覆盖 ValueType.Equals(Object)。)

System_CAPS_pubmethodEquals(Single)

返回一个值,该值指示此实例和指定的 Single 对象是否表示相同的值。

System_CAPS_pubmethodGetHashCode()

返回此实例的哈希代码。(覆盖 ValueType.GetHashCode()。)

System_CAPS_pubmethodGetType()

获取当前实例的 Type(继承自 Object。)

System_CAPS_pubmethodGetTypeCode()

返回值类型 TypeCodeSingle

System_CAPS_pubmethodSystem_CAPS_staticIsInfinity(Single)

返回一个值,该值指示指定数字是计算为负无穷大还是正无穷大。

System_CAPS_pubmethodSystem_CAPS_staticIsNaN(Single)

返回一个值,该值指示指定的值是否不为数字 (NaN)。

System_CAPS_pubmethodSystem_CAPS_staticIsNegativeInfinity(Single)

返回一个值,通过该值指示指定数字是否计算为负无穷大。

System_CAPS_pubmethodSystem_CAPS_staticIsPositiveInfinity(Single)

返回一个值,通过该值指示指定数字是否计算为正无穷大。

System_CAPS_pubmethodSystem_CAPS_staticParse(String)

将数字的字符串表示形式转换为它的等效单精度浮点数。

System_CAPS_pubmethodSystem_CAPS_staticParse(String, IFormatProvider)

将具有指定区域性特定格式的数字的字符串表示形式转换为它的等效单精度浮点数。

System_CAPS_pubmethodSystem_CAPS_staticParse(String, NumberStyles)

将具有指定样式的数字的字符串表示形式转换为它的等效单精度浮点数。

System_CAPS_pubmethodSystem_CAPS_staticParse(String, NumberStyles, IFormatProvider)

将具有指定样式和区域性特定格式的数字的字符串表示形式转换为它的等效单精度浮点数。

System_CAPS_pubmethodToString()

将此实例的数值转换为其等效的字符串表示形式。(覆盖 ValueType.ToString()。)

System_CAPS_pubmethodToString(IFormatProvider)

使用指定的区域性特定格式信息,将此实例的数值转换为它的等效字符串表示形式。

System_CAPS_pubmethodToString(String)

使用指定的格式,将此实例的数值转换为它的等效字符串表示形式。

System_CAPS_pubmethodToString(String, IFormatProvider)

使用指定的格式和区域性特定格式信息,将此实例的数值转换为它的等效字符串表示形式。

System_CAPS_pubmethodSystem_CAPS_staticTryParse(String, NumberStyles, IFormatProvider, Single)

将具有指定样式和区域性特定格式的数字的字符串表示形式转换为它的等效单精度浮点数。 一个指示转换是否成功的返回值。

System_CAPS_pubmethodSystem_CAPS_staticTryParse(String, Single)

将数字的字符串表示形式转换为它的等效单精度浮点数。 一个指示转换是否成功的返回值。

名称说明
System_CAPS_pubfieldSystem_CAPS_staticEpsilon

表示大于零的最小正 Single 值。 此字段为常数。

System_CAPS_pubfieldSystem_CAPS_staticMaxValue

表示 Single 的最大可能值。 此字段为常数。

System_CAPS_pubfieldSystem_CAPS_staticMinValue

表示 Single 的最小可能值。 此字段为常数。

System_CAPS_pubfieldSystem_CAPS_staticNaN

表示非数字 (NaN)。 此字段为常数。

System_CAPS_pubfieldSystem_CAPS_staticNegativeInfinity

表示负无穷。 此字段为常数。

System_CAPS_pubfieldSystem_CAPS_staticPositiveInfinity

表示正无穷。 此字段为常数。

名称说明
System_CAPS_puboperatorSystem_CAPS_staticEquality(Single, Single)

返回一个值,该值指示两个指定的 Single 值是否相等。

System_CAPS_puboperatorSystem_CAPS_staticGreaterThan(Single, Single)

返回一个值,该值指示指定的 Single 值是否大于另一个指定的 Single 值。

System_CAPS_puboperatorSystem_CAPS_staticGreaterThanOrEqual(Single, Single)

返回一个值,该值指示指定的 Single 值是否大于或等于另一个指定的 Single 值。

System_CAPS_puboperatorSystem_CAPS_staticInequality(Single, Single)

返回一个值,该值指示两个指定的 Single 值是否不相等。

System_CAPS_puboperatorSystem_CAPS_staticLessThan(Single, Single)

返回一个值,该值指示指定的 Single 值是否小于另一个指定的 Single 值。

System_CAPS_puboperatorSystem_CAPS_staticLessThanOrEqual(Single, Single)

返回一个值,该值指示指定的 Single 值是否小于或等于另一个指定的 Single 值。

名称说明
System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToBoolean(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToBoolean

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToByte(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToByte

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToChar(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 不支持此转换。 尝试使用此方法将引发 InvalidCastException

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToDateTime(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 不支持此转换。 尝试使用此方法将引发 InvalidCastException

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToDecimal(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToDecimal

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToDouble(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToDouble

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToInt16(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToInt16

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToInt32(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToInt32

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToInt64(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToInt64

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToSByte(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToSByte

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToSingle(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToSingle

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToType(Type, IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToType

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToUInt16(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToUInt16

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToUInt32(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToUInt32

System_CAPS_pubinterfaceSystem_CAPS_privmethodIConvertible.ToUInt64(IFormatProvider)

此 API 支持 产品 基础结构,不应从代码直接使用。 有关此成员的说明,请参阅 IConvertible.ToUInt64

Single 值类型表示单精度 32 位数字,其值范围从-3.402823 e 38 到 + 3.402823 e 38,以及正或负零 PositiveInfinity, ,NegativeInfinity, ,并不是数字 (NaN)。 它被用于表示的值 (如行星或星系之间的距离) 极大或非常小 (例如,一种材料千克分子批量) 和程序通常是不精确 (如从地球到另一个太阳系的距离)。 Single 类型符合 IEC 60559: 1989 (IEEE 754) 二进制浮点算术标准。

本主题包括以下各节:

System.Single 提供用于比较此类型,将实例的值转换为其字符串表示形式,并将数字的字符串表示形式转换为此类型的实例的实例方法。 有关如何格式规范代码控制的字符串表示形式的值类型的信息,请参阅 .NET Framework 中的格式化类型, ,标准数字格式字符串, ,和 自定义数字格式字符串

Single 数据类型将单精度浮点值存储在 32 位的二进制格式下, 表中所示︰

部件

有效位数或尾数

0-22

指数

23-30

登录 (0 = 正数、 1 = 负)

31

就像小数部分不能精确表示小数部分的某些值 (如 1/3 或 Math.PI),二进制分数的形式不能表示某些小数部分值。 例如,2/10,精确地由为小数部分为.2,由为二进制分数,具有模式"1100"重复为无穷大.0011111001001100 表示。 在这种情况下,浮点值提供一个数字,它表示的不精确表示。 通常执行其他数学运算的原始浮点值会增加其缺乏精度。 例如,如果您比较.3 表示通过 10 相乘的结果,并且添加到.3 表示.3 表示九次,您将看到这种添加生成的不太精确的结果,因为它涉及到八个乘法比的更多操作。 请注意,这一差别是很明显,仅当显示两个 Single 值通过使用"R" 标准数字格式字符串, ,而后者如果有必要,将显示所有 9 位精度支持 Single 类型。

using System;

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

      Console.WriteLine(".2 * 10:           {0:R}", result1);
      Console.WriteLine(".2 Added 10 times: {0:R}", result2);
   }
}
// The example displays the following output:
//       .2 * 10:           2
//       .2 Added 10 times: 2.00000024

一些数字,不能精确表示为小数部分的二进制值,因为浮点数可以只是近似的实数值。

所有的浮点数必须有限的数量的有效位,这还确定了浮点值如何准确模拟实数。 一个 Single 值具有最多 7 十进制数字的精度,尽管它在内部维护最多为 9 位。 这意味着某些浮点运算可能缺少要更改的浮点值的精度。 下面的示例定义一个大型的单精度浮点值,并将该产品的 Single.Epsilon 和 1 千万亿给它。 但是,该产品是太小,无法修改原始的浮点值。 其最小有效位是千分位,而该产品中的最高有效位是 1-312

using System;

public class Example
{
   public static void Main()
   {
      Single value = 123456789e4f;
      Single additional = Single.Epsilon * 1e12f;
      Console.WriteLine("{0} + {1} = {2}", value, additional, 
                                           value + additional);
   }
}
// The example displays the following output:
//    1.234568E+12 + 1.401298E-33 = 1.234568E+12

受限制的精度的浮点数的具有以下若干影响︰

  • 两个看起来相等对于特定精度的浮点数可能比较结果不相等,因为其最低有效位不同。 在下面的示例中,一系列数字加在一起,并具有其预期总比较其总量。 尽管两个值看起来相同,调用 Equals 方法表示它们不是。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          Single[] values = { 10.01f, 2.88f, 2.88f, 2.88f, 9.0f };
          Single result = 27.65f;
          Single total = 0f;
          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:R}) does not equal the total ({1:R}).",
                               total, result); 
       }
    }
    // The example displays the following output:
    //      The sum of the values (27.65) does not equal the total (27.65).   
    //
    // 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.6500015) does not equal the total (27.65).   
    

    如果更改中的格式项 Console.WriteLine(String, Object, Object) 语句从 {0}{1}{0:R}{1:R} 以显示全部有效数字,这两个 Single 很明显,这两个值不相等由于精度损失在加法操作期间的值。 在这种情况下,通过调用来解决此问题 Math.Round(Double, Int32) 方法要舍入 Single 在执行比较前所需精度的值。

  • 使用浮点数的算术或比较运算不一定产生相同的结果如果使用的十进制数,因为二进制浮点数可能不等于十进制数。 前面的示例阐释了这通过显示相乘.3 表示通过 10 和添加到.3 表示.3 表示九次的结果。

    重要的小数部分值的数值运算的准确性时,请使用 Decimal 类型而不是 Single 类型。 当使用超出范围的整数值的数值运算的准确性 Int64UInt64 类型是重要的是,使用 BigInteger 类型。

  • 值可能无法往返,如果涉及浮点数。 如果某项操作将原始浮点数转换为另一种形式,相反运算将转换回浮点数,转换后的形式,并且最终浮点数等同于原始浮点数,值被认为保存/还原。 往返行程可能会失败,因为一个或多个最低有效位数丢失或更改在转换中。 在下面的示例中,三个 Single 值转换为字符串,并将其保存到文件中。 如输出所示,尽管看起来是相同的值,已还原的值不相等的原始值。

    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Singles.dat");
          Single[] values = { 3.2f/1.11f, 1.0f/3f, (float) Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) {
             sw.Write(values[ctr].ToString());
             if (ctr != values.Length - 1)
                sw.Write("|");
          }      
          sw.Close();
    
          Single[] restoredValues = new Single[values.Length];
          StreamReader sr = new StreamReader(@".\Singles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Single.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.882883 <> 2.882883
    //       0.3333333 <> 0.3333333
    //       3.141593 <> 3.141593
    

    在这种情况下,值可以是成功往返过程通过使用"R" 标准数字格式字符串 要保留的完全精度 Single 值,如以下示例所示。

    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Singles.dat");
          Single[] values = { 3.2f/1.11f, 1.0f/3f, (float) Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) 
             sw.Write("{0:R}{1}", values[ctr], ctr < values.Length - 1 ? "|" : "" );
    
          sw.Close();
    
          Single[] restoredValues = new Single[values.Length];
          StreamReader sr = new StreamReader(@".\Singles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Single.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.882883 = 2.882883
    //       0.3333333 = 0.3333333
    //       3.141593 = 3.141593
    
  • Single 值具有比精度降低 Double 值。 一个 Single 值转换为看似等效 Double 通常不等于 Double 因为存在差异精度的值。 在下面的示例中,相同的除法运算的结果赋给 Double 值和一个 Single 值。 之后 Single 值强制转换为 Double, ,两个值的比较显示它们不相等。

    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
    

    若要避免此问题,或者使用 Double 数据类型代替了 Single 数据类型或使用 Round 方法,以便这两个值具有相同的精度。

将被视为相等,两个 Single 值必须表示完全相同的值。 但是,由于精度值之间的差异或由于由一个或两个值的精度损失,应该经常是完全相同的浮点值会是由于其最低有效位之间的差异不相等。 因此,调用 Equals 方法来确定两个值是否相等或对调用 CompareTo 方法来确定两个区域之间的关系 Single 值,通常会产生意外的结果。 这是很明显的以下示例中,其中两个显然等于 Single 值会是不相等,因为第一个值具有 7 位精度,而第二个值具有 9。

using System;

public class Example
{
   public static void Main()
   {
      float value1 = .3333333f;
      float value2 = 1.0f/3;
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
   }
}
// The example displays the following output:
//        0.3333333 = 0.333333343: False

计算的值,再执行不同的代码路径和程序中操作不同的方法通常证明是不相等。 在下面的示例中,一个 Single 平方值,并且然后计算平方根以还原为原始值。 第二个 Single 乘以 3.51 和平方之前的结果的平方根除以 3.51 以还原为原始值。 尽管看起来完全相同,这两个值对的调用 Equals(Single) 方法指示它们是否不相等。 使用"R"标准格式字符串来返回一个结果字符串,显示每个的全部有效数字 Single 值显示第二个值是.0000000000001 比第一个更少。

using System;

public class Example
{
   public static void Main()
   {
      float value1 = 10.201438f;
      value1 = (float) Math.Sqrt((float) Math.Pow(value1, 2));
      float value2 = (float) Math.Pow((float) value1 * 3.51f, 2);
      value2 = ((float) Math.Sqrt(value2)) / 3.51f;
      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:
//       10.20144 = 10.20144: False
//       
//       10.201438 = 10.2014389

在发生精度损失可能会影响比较的结果的情况下,可以使用以下方法,而不是调用 EqualsCompareTo 方法︰

  • 调用 Math.Round 方法,以确保这两个值具有相同的精度。 下面的示例修改前面的示例以使用这种方法,以便两个小数部分值相等。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float value1 = .3333333f;
          float value2 = 1.0f/3;
          int precision = 7;
          value1 = (float) Math.Round(value1, precision);
          value2 = (float) 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
    

    请注意,精度问题仍然适用于的中点值舍入。 有关更多信息,请参见 Math.Round(Double, Int32, MidpointRounding) 方法。

  • 测试而不是相等的大致相等性。 这种技术,您需要定义任一绝对量所依据的两个值可以与不同,但仍要相等,或定义时所依据的较小值可以偏离更大的值相对量。

    System_CAPS_warning警告

    Single.Epsilon 有时也用作两个区域之间的距离的绝对度量单位 Single 值时测试是否相等。 但是, Single.Epsilon 测量的最小可能值,可以添加或从中减去 Single 值为零。 对于大多数正和负 Single 值、 的值 Single.Epsilon 太小以致无法检测到。 因此,除了为零的值,不建议在相等性测试中的使用它。

    下面的示例使用后一种方法来定义 IsApproximatelyEqual 用于测试两个值之间的相对差值方法。 它还形成了鲜明对比的调用的结果 IsApproximatelyEqual 方法和 Equals(Single) 方法。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float one1 = .1f * 10;
          float one2 = 0f;
          for (int ctr = 1; ctr <= 10; ctr++)
             one2 += .1f;
    
          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, .000001f));   
       }
    
       static bool IsApproximatelyEqual(float value1, float value2, float 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 = 1.00000012: False
    //       1 is approximately equal to 1.00000012: True
    

具有浮点值的操作不会引发异常,与不同的是具有整数类型,由零个或溢出非法操作,如部门的情况下引发异常的操作。 相反,在这些情况下,浮点运算的结果是零个、 正无穷大、 负无穷大或非数值 (NaN):

  • 如果浮点运算的结果对于目标格式太小,则结果为零。 原因可能相乘两个非常小的浮点数,如以下示例所示。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float value1 = 1.163287e-36f;
          float value2 = 9.164234e-25f;
          float result = value1 * value2;
          Console.WriteLine("{0} * {1} = {2}", value1, value2, result);
          Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0f));
       }
    }
    // The example displays the following output:
    //       1.163287E-36 * 9.164234E-25 = 0
    //       0 = 0: True
    
  • 如果浮点运算的结果的大小超出目标格式的范围,该操作的结果是 PositiveInfinityNegativeInfinity, 以适合结果的符号。 溢出操作的结果 Single.MaxValuePositiveInfinity, ,和溢出的运算结果 Single.MinValueNegativeInfinity, ,如下面的示例所示。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          float value1 = 3.065e35f;
          float value2 = 6.9375e32f;
          float result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Single.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}\n", 
                            Single.IsNegativeInfinity(result));
    
          value1 = -value1;
          result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Single.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}", 
                            Single.IsNegativeInfinity(result));
       }
    }                                                                 
    
    // The example displays the following output:
    //       PositiveInfinity: True
    //       NegativeInfinity: False
    //       
    //       PositiveInfinity: False
    //       NegativeInfinity: True
    

    PositiveInfinity 也被零除与正被除数,可能会造成一个除法运算和 NegativeInfinity 通过负被除数的零的除法运算的结果。

  • 如果浮点运算无效,操作的结果是 NaN 例如, NaN 引起以下操作︰

    • 被零除与被除数为零。 注意部门,其他情况下由零个结果中任意一种 PositiveInfinityNegativeInfinity

    • 具有无效的输入任何浮点操作。 例如,试图找到负数值的平方根返回 NaN

    • 其值的参数与任何操作 Single.NaN

Single 结构不定义任何显式或隐式转换运算符; 相反,由编译器实现的转换。

下表列出了可能的转换值的其他基元数值类型到 Single 值,它还指示扩大或收缩转换以及是否生成 Single 可能具有比原始值的精度降低。

扩大/收缩转换

可能丢失精度

Byte

Widening

No

Decimal

Widening

请注意,C# 要求强制转换运算符。

可以。 Decimal 支持 29 个小数位数的精度; Single 支持 9。

Double

收缩;超出范围值转换为 Double.NegativeInfinityDouble.PositiveInfinity

可以。 Double 支持精度; 17 个小的数位 Single 支持 9。

Int16

Widening

No

Int32

Widening

可以。 Int32 支持 10 个十进制数字的精度; Single 支持 9。

Int64

Widening

可以。 Int64 支持 19 十进制数字的精度; Single 支持 9。

SByte

Widening

No

UInt16

Widening

No

UInt32

Widening

可以。 UInt32 支持 10 个十进制数字的精度; Single 支持 9。

UInt64

Widening

可以。 Int64 支持精度; 20 个十进制的数字 Single 支持 9。

以下示例将转换为其他基元数值类型的最小值或最大值 Single 值。

using System;

public class Example
{
   public static void Main()
   {
      dynamic[] values = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
                           Decimal.MaxValue, Double.MinValue, Double.MaxValue,
                           Int16.MinValue, Int16.MaxValue, Int32.MinValue,
                           Int32.MaxValue, Int64.MinValue, Int64.MaxValue,
                           SByte.MinValue, SByte.MaxValue, UInt16.MinValue,
                           UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
                           UInt64.MinValue, UInt64.MaxValue };
      float sngValue;
      foreach (var value in values) {
         if (value.GetType() == typeof(Decimal) ||
             value.GetType() == typeof(Double))
            sngValue = (float) value;
         else
            sngValue = value;
         Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
                           value, value.GetType().Name,
                           sngValue, sngValue.GetType().Name);
      }
   }
}
// The example displays the following output:
//       0 (Byte) --> 0 (Single)
//       255 (Byte) --> 255 (Single)
//       -79228162514264337593543950335 (Decimal) --> -7.92281625E+28 (Single)
//       79228162514264337593543950335 (Decimal) --> 7.92281625E+28 (Single)
//       -1.79769313486232E+308 (Double) --> -Infinity (Single)
//       1.79769313486232E+308 (Double) --> Infinity (Single)
//       -32768 (Int16) --> -32768 (Single)
//       32767 (Int16) --> 32767 (Single)
//       -2147483648 (Int32) --> -2.14748365E+09 (Single)
//       2147483647 (Int32) --> 2.14748365E+09 (Single)
//       -9223372036854775808 (Int64) --> -9.223372E+18 (Single)
//       9223372036854775807 (Int64) --> 9.223372E+18 (Single)
//       -128 (SByte) --> -128 (Single)
//       127 (SByte) --> 127 (Single)
//       0 (UInt16) --> 0 (Single)
//       65535 (UInt16) --> 65535 (Single)
//       0 (UInt32) --> 0 (Single)
//       4294967295 (UInt32) --> 4.2949673E+09 (Single)
//       0 (UInt64) --> 0 (Single)
//       18446744073709551615 (UInt64) --> 1.84467441E+19 (Single)

此外, DoubleDouble.NaN, ,Double.PositiveInfinity, ,和 Double.NegativeInfinity 到隐蔽 Single.NaN, ,Single.PositiveInfinity, ,和 Single.NegativeInfinity, 分别。

请注意,对某些数值类型的值转换 Single 值可以包含发生精度损失。 如示例所示,转换时,为可能发生精度损失 Decimal, ,Double, ,Int32, ,Int64, ,UInt32, ,和 UInt64 值复制到 Single 值。

转换 Single 值赋给 Double 是扩大转换。 如果,转换可能会导致精度损失 Double 类型不具有的精确表示形式 Single 值。

转换 Single 值为任何基元数值数据类型的值而不 Double 是收缩转换,且需要强制转换运算符 (在 C# 中) 或 (在 Visual Basic 中) 的转换方法。 不在目标数据类型范围内定义的目标类型的值 MinValueMaxValue 属性,如下面的表中所示的行为。

目标类型

结果

任何整数类型

OverflowException 异常,则转换发生在 checked 上下文中。

如果在转换发生在未检查的上下文 (在 C# 中默认值),转换操作成功,但值溢出。

Decimal

OverflowException 异常,

此外, Single.NaN, ,Single.PositiveInfinity, ,和 Single.NegativeInfinity 引发 OverflowException 转换为整数在 checked 的上下文中,但这些值溢出时转换为未检查的上下文内的整数。 对于转换到 Decimal, ,它们始终引发 OverflowException 对于转换到 Double, ,它们将转换为 Double.NaN, ,Double.PositiveInfinity, ,和 Double.NegativeInfinity, 分别。

请注意,精度损失的转换可能会导致 Single 到另一种数值类型的值。 在将非整型的转换的情况下 Double 值,如示例输出所示,小数部分时,丢失 Single 值舍入 (如 Visual Basic 中) 或 (如 C#) 被截断。 对于转换到 DecimalSingle 值, Double 值中的目标数据类型不能有精确的表示形式。

下面的示例将大量 Single 到几个其他数值类型的值。 转换发生在 checked 上下文中在 Visual Basic (默认值) 和 C# 中 (由于 检查 关键字)。 该示例的输出显示转换的结果中这两个检查未检查的上下文。 可以在 Visual Basic 中未检查的上下文中执行转换,通过用 /removeintchecks+ 编译器开关和 C# 通过注释掉 checked 语句。

using System;

public class Example
{
   public static void Main()
   {
      float[] values = { Single.MinValue, -67890.1234f, -12345.6789f,
                         12345.6789f, 67890.1234f, Single.MaxValue,
                         Single.NaN, Single.PositiveInfinity,
                         Single.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);
            }

            Double dblValue = value;
            Console.WriteLine("{0} ({1}) --> {2} ({3})",
                              value, value.GetType().Name,
                              dblValue, dblValue.GetType().Name);
            Console.WriteLine();
         }
      }
   }
}
// The example displays the following output for conversions performed
// in a checked context:
//       Unable to convert -3.402823E+38 to Int64.
//       Unable to convert -3.402823E+38 to UInt64.
//       Unable to convert -3.402823E+38 to Decimal.
//       -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
//
//       -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       Unable to convert -67890.13 to UInt64.
//       -67890.13 (Single) --> -67890.12 (Decimal)
//       -67890.13 (Single) --> -67890.125 (Double)
//
//       -12345.68 (Single) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       Unable to convert -12345.68 to UInt64.
//       -12345.68 (Single) --> -12345.68 (Decimal)
//       -12345.68 (Single) --> -12345.6787109375 (Double)
//
//       12345.68 (Single) --> 12345 (0x0000000000003039) (Int64)
//       12345.68 (Single) --> 12345 (0x0000000000003039) (UInt64)
//       12345.68 (Single) --> 12345.68 (Decimal)
//       12345.68 (Single) --> 12345.6787109375 (Double)
//
//       67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
//       67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
//       67890.13 (Single) --> 67890.12 (Decimal)
//       67890.13 (Single) --> 67890.125 (Double)
//
//       Unable to convert 3.402823E+38 to Int64.
//       Unable to convert 3.402823E+38 to UInt64.
//       Unable to convert 3.402823E+38 to Decimal.
//       3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
//
//       Unable to convert NaN to Int64.
//       Unable to convert NaN to UInt64.
//       Unable to convert NaN to Decimal.
//       NaN (Single) --> NaN (Double)
//
//       Unable to convert Infinity to Int64.
//       Unable to convert Infinity to UInt64.
//       Unable to convert Infinity to Decimal.
//       Infinity (Single) --> Infinity (Double)
//
//       Unable to convert -Infinity to Int64.
//       Unable to convert -Infinity to UInt64.
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Single) --> -Infinity (Double)
// The example displays the following output for conversions performed
// in an unchecked context:
//       -3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -3.402823E+38 (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -3.402823E+38 to Decimal.
//       -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
//
//       -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
//       -67890.13 (Single) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
//       -67890.13 (Single) --> -67890.12 (Decimal)
//       -67890.13 (Single) --> -67890.125 (Double)
//
//       -12345.68 (Single) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
//       -12345.68 (Single) --> 18446744073709539271 (0xFFFFFFFFFFFFCFC7) (UInt64)
//       -12345.68 (Single) --> -12345.68 (Decimal)
//       -12345.68 (Single) --> -12345.6787109375 (Double)
//
//       12345.68 (Single) --> 12345 (0x0000000000003039) (Int64)
//       12345.68 (Single) --> 12345 (0x0000000000003039) (UInt64)
//       12345.68 (Single) --> 12345.68 (Decimal)
//       12345.68 (Single) --> 12345.6787109375 (Double)
//
//       67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
//       67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
//       67890.13 (Single) --> 67890.12 (Decimal)
//       67890.13 (Single) --> 67890.125 (Double)
//
//       3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       3.402823E+38 (Single) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert 3.402823E+38 to Decimal.
//       3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
//
//       NaN (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       NaN (Single) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert NaN to Decimal.
//       NaN (Single) --> NaN (Double)
//
//       Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       Infinity (Single) --> 0 (0x0000000000000000) (UInt64)
//       Unable to convert Infinity to Decimal.
//       Infinity (Single) --> Infinity (Double)
//
//       -Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
//       -Infinity (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
//       Unable to convert -Infinity to Decimal.
//       -Infinity (Single) --> -Infinity (Double)

数值类型的转换的详细信息,请参阅 .NET Framework 中的类型转换.NET Framework 中的类型转换表

Single 结构和相关的类型提供多种方法来执行以下类别的操作︰

  • 值比较 您可以调用 Equals 方法来确定两个 Single 值是否相等,则 CompareTo 方法来确定两个值之间的关系。

    Single 结构还支持一组完整的比较运算符。 例如,可以测试相等,或确定一个值是否大于或等于另一个值。 如果其中一个操作数是 Double, 、 Single 值转换为 Double 之前执行比较。 如果其中一个操作数为整数类型,它将转换为 Single 之前执行比较。 虽然这些扩大转换,但是它们可能会涉及发生精度损失。

    System_CAPS_warning警告

    因为存在差异的精度,两个 Single 您希望相等的值可能会发现不相等,这会影响比较结果。 请参阅 相等性测试 比较两个有关详细信息部分 Single 值。

    您还可以调用 IsNaN, ,IsInfinity, ,IsPositiveInfinity, ,和 IsNegativeInfinity 方法来测试这些特殊值。

  • 数学运算 通过语言编译器和公共中间语言 (CIL) 说明而不是实现常见的算术运算,例如加法、 减法、 乘法和除法 Single 方法。 如果在数学运算中的另一个操作数是 Double, 、 Single 转换为 Double 之前执行此操作和操作的结果也是 Double 值。 如果另一个操作数是整数类型,它将转换为 Single 之前执行此操作和操作的结果也是 Single 值。

    可以通过调用来执行其他数学运算 static (Shared 在 Visual Basic 中) 中的方法 System.Math 类。 其中包括常用的算术的其他方法 (如 Math.Abs, ,Math.Sign, ,和 Math.Sqrt),geometry (如 Math.CosMath.Sin),并计算 (如 Math.Log)。 在所有情况下, Single 值转换为 Double

    您还可以操作中的单个位 Single 值。 BitConverter.GetBytes(Single) 方法返回的位模式中的字节数组。 通过将传递该字节数组转换为 BitConverter.ToInt32 方法中,您还可以保留 Single 值的位模式在一个 32 位整数。

  • 舍入 舍入通常用于为一种技术降低引起的问题的浮点表示形式和精度值之间的差异的影响。 您可以舍入 Single 值通过调用 Math.Round 方法。 但请注意, Single 值转换为 Double 之前调用此方法,并且转换可能涉及发生精度损失。

  • 格式 您可以将转换 Single 值通过调用其字符串表示形式与 ToString 方法或通过使用 复合格式设置 功能。 有关格式字符串如何控制浮点值的字符串表示的信息,请参阅 标准数字格式字符串自定义数字格式字符串 主题。

  • 分析字符串 您可以将转换为浮点值的字符串表示 Single 值通过调用 ParseTryParse 方法。 如果分析操作失败, Parse 方法将引发异常,而 TryParse 方法将返回 false

  • 类型转换,则 Single 结构提供的显式接口实现 IConvertible 接口,支持任何两个标准的.NET Framework 数据类型之间的转换。 语言编译器也支持所有其他标准数值类型除外的转换值的隐式转换 DoubleSingle 值。 以外的其他任何标准数值类型的值的转换 DoubleSingle 是扩大转换,并且不需要强制转换运算符或转换方法的用法。

    但是,32 位和 64 位整数值转换可能会涉及发生精度损失。 下表列出了在 32 位、 64 位的精度的差异和 Double 类型︰

    类型

    最大精度 (以十进制位数)

    内部精度 (以十进制位数)

    Double

    15

    17

    Int32UInt32

    10

    10

    Int64UInt64

    19

    19

    Single

    7

    9

    精度的问题最频繁影响 Single 值转换为 Double 值。 在下面的示例中,生成的相同除法运算的两个值不相等,因为值之一是单精度浮点值转换为 Double

    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
    

通用 Windows 平台
自 8 起可用
.NET Framework
自 1.1 起可用
可移植类库
可移植 .NET 平台 中受支持
Silverlight
自 2.0 起可用
Windows Phone Silverlight
自 7.0 起可用
Windows Phone
自 8.1 起可用

此类型的所有成员都是线程安全。 实际上,看起来要修改实例状态的成员返回使用新值进行初始化的新实例。 作为与任何其他类型,读取和写入对共享变量,其中包含此类型的实例必须保护锁来保证线程安全性。

返回页首
显示: