Exportar (0) Imprimir
Expandir Tudo
Este artigo foi traduzido por máquina. Coloque o ponteiro do mouse sobre as frases do artigo para ver o texto original. Mais informações.
Tradução
Original

Estrutura Single

Representa um número de ponto flutuante de precisão única.

Namespace:  System
Assembly:  mscorlib (em mscorlib.dll)

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

O tipo Single expõe os membros a seguir.

  NomeDescrição
Método públicoCompatível com o XNA FrameworkCompareTo(Object)Compara esta instância em um objeto especificado e retorna um inteiro que indica se o valor desta instância for menor que, igual ou maior que o valor do objeto especificado.
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreCompareTo(Single)Compara esta instância em um número de ponto flutuante de precisão única especificado e retorna um inteiro que indica se o valor desta instância for menor que, igual ou maior que o valor de número de ponto flutuante de precisão única especificado.
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreEquals(Object)Retorna um valor que indica se essa instância é igual a um objeto especificado. (Substitui ValueType.Equals(Object).)
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreEquals(Single)Retorna um valor que indica se essa instância e um objeto especificado de Single representam o mesmo valor.
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreGetHashCode Retorna o hash code para essa instância. (Substitui ValueType.GetHashCode().)
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreGetType Obtém o Type da instância atual. (Herdado de Object.)
Método públicoCompatível com o XNA FrameworkGetTypeCodeRetorna TypeCode para o tipo de valor Single.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreIsInfinityRetorna um valor que indica se o número especificado avaliar ao infinito negativo ou positivo.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreIsNaNRetorna um valor que indica se o valor especificado não é um número (NaN).
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreIsNegativeInfinityRetorna um valor que indica se o número especificado avaliar ao infinito negativo.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreIsPositiveInfinityRetorna um valor que indica se o número especificado avaliar ao infinito positivo.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreParse(String)Converte a representação da cadeia de caracteres de um número no número de ponto flutuante de precisão simples equivalente.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreParse(String, NumberStyles)Converte a representação de cadeia de caracteres de um número em um estilo especificado para seu equivalente de precisão simples de número de ponto flutuante.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreParse(String, IFormatProvider)Converte a representação de cadeia de caracteres de um número em um formato específico a cultura especificado para seu equivalente de precisão simples de número de ponto flutuante.
Método públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreParse(String, NumberStyles, IFormatProvider)Converte a representação de cadeia de caracteres de um número em um estilo especificado e a cultura de formato específico para seu equivalente de precisão simples de número de ponto flutuante.
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreToString()Converte o valor numérico dessa instância na representação da cadeia de caracteres equivalente. (Substitui ValueType.ToString().)
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreToString(IFormatProvider)Converte o valor numérico dessa instância na representação da cadeia de caracteres equivalente usando as informações de formato específicas da cultura especificada.
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreToString(String)Converte o valor numérico dessa instância na representação da cadeia de caracteres equivalente usando o formato especificado.
Método públicoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreToString(String, IFormatProvider)Converte o valor numérico dessa instância na representação da cadeia de caracteres equivalente usando o formato especificado e as informações de formato específicas da cultura especificada.
Método públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreTryParse(String, Single)Converte a representação da cadeia de caracteres de um número no número de ponto flutuante de precisão simples equivalente. Um valor de retorno indica se a conversão foi bem-sucedida ou falhou.
Método públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreTryParse(String, NumberStyles, IFormatProvider, Single)Converte a representação de cadeia de caracteres de um número em um estilo especificado e a cultura de formato específico para seu equivalente de precisão simples de número de ponto flutuante. Um valor de retorno indica se a conversão foi bem-sucedida ou falhou.
Superior

  NomeDescrição
Operador públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreEqualityRetorna um valor que indica se dois valores especificados de Single são iguais.
Operador públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreGreaterThanRetorna um valor que indica se um valor especificado de Single é maior que outro valor especificado de Single .
Operador públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreGreaterThanOrEqualRetorna um valor que indica se um valor especificado de Single é maior ou igual a outro valor especificado de Single .
Operador públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreInequalityRetorna um valor que indica se dois valores especificados de Single não são iguais.
Operador públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreLessThanRetorna um valor que indica se um valor especificado de Single é menor que outro valor especificado de Single .
Operador públicoMembro estáticoCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreLessThanOrEqualRetorna um valor que indica se um valor especificado de Single é menor ou igual a outro valor especificado de Single .
Superior

  NomeDescrição
Campo públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreEpsilonRepresenta o valor positivo o menor de Single que for maior que zero. Este campo é constante.
Campo públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreMaxValueRepresenta o maior valor possível de Single. Este campo é constante.
Campo públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreMinValueRepresenta o valor possível o menor de Single. Este campo é constante.
Campo públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreNaNRepresenta um númeroNaNnão (). Este campo é constante.
Campo públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreNegativeInfinityRepresenta o infinito negativo. Este campo é constante.
Campo públicoMembro estáticoCompatível com o XNA FrameworkCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StorePositiveInfinityRepresenta o infinito positivo. Este campo é constante.
Superior

  NomeDescrição
Implementação explícita da interfaceMétodo particularCom suporte por Biblioteca de Classes PortátilCom suporte em .NET para aplicativos da Windows StoreIComparable.CompareToCompara a instância atual com outro objeto do mesmo tipo e retorna um inteiro que indica se a instância atual precede, segue ou ocorre na mesma posição da ordem de classificação do outro objeto.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToBooleanInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToBoolean.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToByteInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToByte.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToCharInfraestrutura. Esta conversão não é suportada. A tentativa de usar esse método lança um InvalidCastException.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToDateTimeInfraestrutura. Esta conversão não é suportada. A tentativa de usar esse método lança um InvalidCastException.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToDecimalInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToDecimal.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToDoubleInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToDouble.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToInt16Infraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToInt16.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToInt32Infraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToInt32.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToInt64Infraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToInt64.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToSByteInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToSByte.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToSingleInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToSingle.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToTypeInfraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToType.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToUInt16Infraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToUInt16.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToUInt32Infraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToUInt32.
Implementação explícita da interfaceMétodo particularCompatível com o XNA FrameworkIConvertible.ToUInt64Infraestrutura. Para obter uma descrição desse membro, consulte IConvertible.ToUInt64.
Superior

O tipo de valor de Single representa um número de 32 bits de precisão simples com valores que variam de 3.402823e38 negativo a 3.402823e38 positivo, bem como positivos ou negativos zero, PositiveInfinity, NegativeInfinity, e não um número (NaN). O objetivo de representar valores que são extremamente grandes (como distâncias entre planetas ou galáxias) ou muito pequenos (como molecular massa de uma substância em quilogramas) e que são frequentemente imprecisas (como a distância da terra para outro sistema solar). O tipo de Single está em conformidade com o padrão de 60559:1989 de IEC (IEEE 754) para aritmética de ponto flutuante binário.

Este tópico consiste nas seguintes seções:

System.Single fornece métodos para comparar instâncias desse tipo, para converter o valor de uma instância em sua representação de cadeia de caracteres, e para converter a representação de cadeia de caracteres de um número em uma instância deste tipo. Para obter informações sobre como os códigos da especificação do formato controlam a representação de cadeia de caracteres dos tipos de valores, consulte Formatando tipos, Cadeias de caracteres de formato numérico padrão, e Cadeias de caracteres de formato numérico personalizado.

Representação de ponto flutuante e precisão

O tipo de dados de Single armazena valores de ponto flutuante de precisão única em um formato binário de 32 bits, conforme mostrado na seguinte tabela:

Parte

Bit

Significand ou mantissa

0-22

Expoente

23-30

0 = (Sinal positivo, 1 = negativo)

31

Assim como as frações decimais não conseguirão se representar precisamente alguns valores fracionários (como 1/3 ou Math.PI), as frações binários não conseguirão se representar alguns valores fracionários. Por exemplo, 2/10, que é representado por precisamente .2 como uma fração decimal, são representados por .0011111001001100 como uma fração binário, com o padrão “1100” que se repetem ao infinito. Nesse caso, o valor de ponto flutuante fornece uma representação imprecisa o número que representa. Executar operações matemáticas adicionais no valor de ponto flutuante original geralmente aumenta a falta de precisão. Por exemplo, se você comparar os resultados de multiplicar .3 por 10 e adicionar .3 a .3 nove vezes, você verá que a adição gerencia o resultado menos precisas, porque envolve mais que oito operações de multiplicação. Observe que essa disparidade estão aparentes somente se você exibe os valores das duas Single usando o “R” cadeia de caracteres de formatação numérica padrão, que se necessário, que exibe todos os 9 dígitos de precisão suportados por tipo de 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


Como alguns números não podem ser representados exatamente como valores binários fracionários, os números de pontos flutuantes podem ver apenas números reais.

Todos os números de pontos flutuantes têm um número limitado de dígitos significativos, que também determina como exatamente um valor de ponto flutuante aproxima um número real. Um valor de Single contendo até 7 dígitos decimais de precisão, embora um máximo de 9 dígitos seja mantido interiormente. Isso significa que algumas operações de ponto flutuante podem não ter a precisão para alterar um valor de ponto flutuante. O exemplo a seguir define um valor grande de ponto flutuante de precisão única, e adiciona o produto de Single.Epsilon e um quadrillion. No entanto, o produto é muito pequeno alterar o valor de ponto flutuante original. O menos dígito significante é milésimos, enquanto o dígito o mais significativo sobre o produto é 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


A precisão limitada de um número de ponto flutuante tem várias consequências:

  • Dois números de ponto flutuante que pareçam iguais para uma determinada precisão podem não ser comparados como iguais porque seus dígitos menos significantes são diferentes. No exemplo, uma série de números são unidas, e o total é comparado com o total esperado. Embora os dois valores pareçam ser os mesmos, uma chamada ao método de Equals indica que não são.

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

    Se você alterar os itens de formato na instrução de Console.WriteLine(String, Object, Object) de {0} e de {1} a {0:R} e a {1:R} para exibir todos os dígitos significativos dos dois valores de Single , é claro que os dois valores são diferentes devido à perda de precisão durante as operações de adição. Nesse caso, o problema pode ser resolvido chamando o método de Math.Round(Double, Int32) para arredondar os valores de Single à precisão desejada antes de executar a comparação.

  • Uma operação matemática ou de comparação que use um número de ponto flutuante talvez não produza o mesmo resultado se um número decimal for usado, como o número de ponto flutuante binário não pode ser igual ao número decimal. Um exemplo anterior ilustrou este exibindo o resultado de multiplicar .3 por 10 e adicionar .3 a .3 nove vezes.

    Quando a precisão em operações numéricas com os valores fracionários é importante, use o tipo de Decimal em vez do tipo de Single . Quando a precisão em operações numéricas com os valores integrais além do intervalo dos tipos de Int64 ou de UInt64 é importante, use o tipo de BigInteger .

  • Um valor não pode viagem de ida e volta se um número de ponto flutuante estiver envolvido. Um valor é considerado como a viagem de ida e volta se uma operação converte um número de ponto flutuante original para outra forma, uma operação inversa transforma a forma convertida novamente a um número de ponto flutuante, e o número de ponto flutuante final não é igual ao número de ponto flutuante original. A viagem de ida e volta pode falhar porque um ou mais dígitos menos significantes são perdidos ou alterados na conversão. No exemplo, três valores de Single são convertidos em cadeias de caracteres e salvos em um arquivo. Como a saída mostra os valores, embora pareçam ser idênticos, os valores restaurados não forem iguais aos valores originais.

    
    Imports System.IO
    
    Module Example
       Public Sub Main()
          Dim sw As New StreamWriter(".\Singles.dat")
          Dim values() As Single = { 3.2/1.11, 1.0/3, CSng(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 Single
          Dim sr As New StreamReader(".\Singles.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) = Single.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.882883 <> 2.882883
    '        0.3333333 <> 0.3333333
    '        3.141593 <> 3.141593
    
    
    
    
    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
    
    
    
    
    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
    
    
    

    Nesse caso, os valores podem com êxito redonda ser tropeçados usando o “R” cadeia de caracteres de formatação numérica padrão para preservar a precisão completa de valores de Single , conforme mostrado no exemplo a seguir.

  • os valores deSingle têm menos precisão dos valores de Double . Um valor de Single que é convertido em Double aparentemente equivalente geralmente não é igual ao valor de Double devido às diferenças na precisão. No exemplo a seguir, o resultado de operações idênticas de divisão é atribuído a um valor de Double e um valor de Single . Depois que o valor de Single é convertido em Double, uma comparação dos dois valores mostra que são diferentes.

    
    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
    
    
    

    Para evitar esse problema, use o tipo de dados de Double no lugar do tipo de dados de Single , ou usa o método de Round de modo que ambos os valores têm a mesma precisão.

Testando igualdade

Para ser considerado igual, dois valores de Single devem representar valores idênticos. No entanto, devido às diferenças na precisão entre valores, ou devido à perda de precisão por um ou ambos valores, valores de ponto flutuante que devem ser ativar que geralmente idêntico a forma diferente por causa das diferenças em seus dígitos menos significantes. No resultado, as chamadas para o método de Equals para determinar se dois valores são iguais, ou chamadas para o método de CompareTo para determinar a relação entre dois valores de Single , são frequentemente resultados inesperados. Isso é evidente no exemplo a seguir, onde dois valores iguais aparentemente de Single despejam ser diferentes, como o primeiro valor tem 7 dígitos de precisão, mas o segundo valor tem 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


Os valores calculados que seguem diferentes caminhos de código e que são manipulados de modos diferentes exemplo frequentemente ser diferentes. No exemplo a seguir, um valor de Single é a, e a raiz quadrada é calculada em para restaurar o valor original. Um segundo Single é multiplicado por 3,51 e a antes da raiz quadrada do resultado seja dividido por 3,51 para restaurar o valor original. Embora os dois valores pareçam ser idênticos, uma chamada ao método de Equals(Single) indica que não são iguais. Usando a cadeia de caracteres de formato padrão de “R” para retornar um resultado cadeia de caracteres que exibe todos os dígitos significativos de cada valor de Single mostra que o segundo valor .0000000000001 é menor que o primeiro.


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


Nos casos em que uma perda de precisão é provável que afete o resultado de uma comparação, você pode usar as seguintes técnicas em vez de chamar o método de Equals ou de CompareTo :

  • Chame o método de Math.Round para garantir que ambos os valores têm a mesma precisão. O exemplo a seguir altera um exemplo anterior para usar esta abordagem de modo que dois valores fracionários sejam equivalentes.

    
    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
    
    
    

    Observe que o problema de precisão ainda se aplica a arredondamentos de valores de ponto médio. Para obter mais informações, consulte o método Math.Round(Double, Int32, MidpointRounding).

  • Testar a igualdade aproximada em vez de igualdade. Essa técnica requer que você defina um absoluta a quantidade pela qual os dois valores podem diferir mas ainda para ser iguais, ou que você define uma quantia relativa por que o menor valor pode divergir de valor maior.

    Observação de cuidadoCuidado

    Single.Epsilon às vezes é usado como uma medida de distância absoluta entre dois valores de Single ao testar a igualdade. No entanto, Single.Epsilon ultrapassar o valor possível ao menor que podem ser adicionados, ou ser subtraído de Single , cujo valor é zero. Para os valores mais positivos e negativos dos mais Single , o valor de Single.Epsilon é muito pequeno para ser detectado. Consequentemente, com exceção dos valores que são zero, não recomendamos o uso em testa a igualdade.

    O exemplo a seguir usa a última abordagem para definir um método de IsApproximatelyEqual que testa a diferença relativa entre dois valores. Também contrasta o resultado de chamadas para o método de IsApproximatelyEqual e ao método de 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
    
    
    

Valores de ponto flutuante e exceções

As operações com os valores de ponto flutuante não lançam exceções, em vez de operações com os tipos integrais, que lançam exceções em casos de operações ilegais como divisão por zero ou estouro. Em vez disso, nessas situações, o resultado de uma operação de ponto flutuante for zero, infinito positivo, infinito negativo, ou não é um número (NaN):

  • Se o resultado de uma operação de ponto flutuante for muito pequeno para o formato de destino, o resultado será nulo. Isso pode ocorrer quando dois números de ponto flutuante muito pequenos são multiplicados, conforme mostrado no exemplo a seguir.

    
    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
    
    
    
  • Se o valor do resultado de uma operação de ponto flutuante excede o intervalo do formato de destino, o resultado da operação é PositiveInfinity ou NegativeInfinity, conforme apropriado para o sinal do resultado. O resultado de uma operação que não Single.MaxValue é PositiveInfinity, e o resultado de uma operação que os estouros Single.MinValue são NegativeInfinity, conforme mostrado no exemplo a seguir.

    
    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 também resulta de uma divisão por zero com um dividendo positivo, e os resultados de NegativeInfinity de uma divisão por zero com um dividendo negativo.

  • Se uma operação de ponto flutuante não é válido, o resultado da operação é NaN. Por exemplo, NaN resultados das seguintes operações:

    • Divisão por zero com um dividendo de zero. Observe que outros exemplos de divisão por zero resultam em PositiveInfinity ou a NegativeInfinity.

    • Qualquer operação de ponto flutuante com a entrada inválida. Por exemplo, uma tentativa de encontrar a raiz quadrada de um valor negativo retorna NaN.

    • Qualquer operação com um argumento cujo valor é Single.NaN.

Funcionalidade de ponto flutuante

A estrutura de Single e os tipos relacionados fornece métodos para executar as seguintes categorias de operações:

  • Comparação de valores. Você pode chamar o método de Equals para determinar se dois valores de Single forem iguais, ou o método de CompareTo para determinar a relação entre dois valores.

    A estrutura de Single também oferece suporte a um conjunto completo de operadores de comparação. Por exemplo, você pode testar a igualdade ou desigualdade, ou a determinar se um valor é maior ou igual a outro. Se um dos operandos for Double, o valor de Single será convertido em Double antes de executar a comparação. Se um dos operandos for um tipo completo, é convertido em Single antes de executar a comparação. Embora esses sejam alargando conversões, podem envolver uma perda de precisão.

    Observação de cuidadoCuidado

    Devido às diferenças na precisão, dois valores de Single que você espera ser igual despejar podem ser diferentes, o que afeta o resultado da comparação. Consulte a seção de Testa a igualdade para obter mais informações sobre como comparar dois valores de Single .

    Você também pode chamar IsNaN, IsInfinity, IsPositiveInfinity, e os métodos de IsNegativeInfinity para testar esses valores especiais.

  • Operações matemáticas. Operações aritméticas comuns como adição, subtração, multiplicação e a divisão, são implementadas pelos compiladores e instruções de linguagem comum (CIL) de linguagem intermediária em vez de pelos métodos de Single . Se o outro operando em uma operação matemática é Double, Single será convertido em Double antes de executar a operação, e o resultado da operação também um valor de Double . Se o outro operando for um tipo completo, é convertido em Single antes de executar a operação, e o resultado da operação também um valor de Single .

    Você pode executar outras operações matemáticas chamando métodos de static (Shared no Visual Basic) na classe de System.Math . Esses incluem métodos adicionais de uso geral para aritmética (como Math.Abs, Math.Sign, e Math.Sqrt), a geometria (como Math.Cos e Math.Sin), e o cálculo (como Math.Log). Em todos os casos, o valor de Single é convertido em Double.

    Você também pode manipular os bits individuais em um valor de Single . O método de BitConverter.GetBytes(Single) retorna o padrão de bits em uma matriz de bytes. Passando a matriz de bytes ao método de BitConverter.ToInt32 , você também pode preservar o padrão de bits do valor de Single em um inteiro de 32 bits.

  • Arredondamento. Arredondamento é frequentemente usado como uma técnica para reduzir o impacto das diferenças entre os valores provocados por problemas de representação de ponto flutuante e a precisão. Você pode arredonda um valor de Single chamando o método de Math.Round . No entanto, observe que o valor de Single será convertido em Double antes que o método seja chamado, e a conversão pode envolver uma perda de precisão.

  • Formatar. Você pode converter um valor de Single em sua representação de cadeia de caracteres chamando o método de ToString ou usando o recurso de formatação composta . Para obter informações sobre como as cadeias de formato controlam a representação de cadeia de caracteres de valores de ponto flutuante, consulte os tópicos de Cadeias de caracteres de formato numérico padrão e de Cadeias de caracteres de formato numérico personalizado .

  • Cadeias de caracteres de análise. Você pode converter representação de cadeia de caracteres de um valor de ponto flutuante a um valor de Single chamando o método de Parse ou de TryParse . Se a operação de análise falhar, o método de Parse gerou uma exceção, enquanto o método de TryParse retorna false.

  • Conversão de tipos. A estrutura de Single fornece uma implementação da interface explícita para a interface de IConvertible , que da suporte à conversão entre quaisquer dois tipos de dados padrão do.NET Framework. Os compiladores de idioma também dão suporte à conversão implícita de valores para todos os tipos numéricos padrão restantes com exceção de conversão de Double aos valores de Single . A conversão de um valor de qualquer tipo numérico padrão diferente Double a Single é uma conversão da e não requer o uso de um método de operador ou de conversão de conversão.

    Entretanto, a conversão de valores inteiros de 32 bits e de 64 bits pode envolver uma perda de precisão. A tabela a seguir lista as diferenças na precisão dos tipos de 32 bits, de 64 bits, e de Double :

    Tipo

    Precisão máxima (em dígitos decimais)

    Precisão interna (em dígitos decimais)

    Double

    15

    17

    Int32 e UInt32

    10

    10

    Int64 e UInt64

    19

    19

    Single

    7

    9

    O problema de precisão afeta com mais frequência os valores de Single que são convertidos em valores de Double . No exemplo a seguir, dois valores gerados por operações idênticas de particionamento são diferentes, porque um dos valores é um valor de ponto flutuante de precisão única que é convertido em 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
    
    
    

.NET Framework

Com suporte em: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Com suporte em: 4, 3.5 SP1

Biblioteca de Classes Portátil

Com suporte em: Biblioteca de Classes Portátil

.NET para aplicativos da Windows Store

Com suporte em: Windows 8

.NET para aplicativos do Windows Phone

Com suporte em: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Função Server Core sem suporte), Windows Server 2008 R2 (Função Server Core com suporte com o SP1 ou posterior, Itanium sem suporte)

O .NET Framework não oferece suporte a todas as versões de cada plataforma. Para obter uma lista das versões com suporte, consulte Requisitos do sistema do .NET Framework.

Todos os membros desse tipo são segmento seguro. Os membros que aparecem para modificar o estado da instância, na verdade, retornam uma nova instância inicializada com o novo valor. Como com qualquer outro tipo, leitura e gravação a uma variável compartilhada que contém uma instância desse tipo deve ser protegida por um bloqueio para garantir segurança de segmentos.

Contribuições da comunidade

ADICIONAR
Mostrar:
© 2015 Microsoft