Existem números que não são representáveis na base 10, mas podem ser representados na base 2?

40

C# tem o decimal type que é usado para números que precisam de informações exatas representação na base 10. Por exemplo, 0.1 não pode ser representado na base 2 (por exemplo, float e double ) e sempre será uma aproximação quando armazenado em variáveis que são desses tipos.

Eu queria saber se o fato reverso também era possível. Existem números que não são representáveis na base 10, mas podem ser representados na base 2 (caso em que eu gostaria de usar um float em vez de um decimal para lidar com eles)?

    
por Max 25.04.2014 / 17:27
fonte

3 respostas

103

Aqui está a chave para o seu dilema: 10 é o produto de 2 e 5 . Você pode representar qualquer número exatamente na base 10 decimais que é k * 1/2 n * 1/5 m onde k , n e m são inteiros.

Alternativamente formulado - se o número n em 1 / n contiver um fator que não faz parte dos fatores da base, o número não poderá ser representado exatamente em um número fixo de dígitos no binário / decimal / qualquer expansão desse número - terá uma parte repetida. Por exemplo, 1/15 = 0,0666666666 .... porque 3 (15 = 3 * 5) não é um fator de 10.

Assim, tudo o que é capaz de ser representado exatamente na base 2 (k * 1/2 n ) pode ser representado exatamente na base 10.

Além disso, há a questão de quantos dígitos / bits você está usando para representar o número. Existem alguns números que podem ser exatamente representados em alguma base, mas é necessário mais do que alguns dígitos / bits para fazer.

Em binário, o número 1/10 que é convenientemente 0,1 em decimal não pode ser representado como um número que pode ser representado em um número fixo de bits em binário. Em vez disso, o número é 0,00011001100110011 ... 2 (com a parte 0011 repetindo para sempre).

Vamos olhar o número 1 2 / 1010 2 um pouco mais de perto.

          ____                  
       0.00011                  
     +---------                 
1010 | 1.00000                  
       0                        
       --                       
       1 0                      
         0                      
       ----                     
       1 00 ---------+          
          0          |          
       -----         |          
       1 000         |          
           0         |          
       ------        | repeating
       1 0000        | block    
         1010        |          
       ------        |          
          1100       |          
          1010       |          
          ----       |          
            100  ----+          

Este é exatamente o mesmo tipo de coisa que você recebe quando tenta fazer a divisão longa por 1/3.

1/10, quando fatorado é 1 / (2 1 * 5 1 ). Para a base 10 (ou qualquer múltiplo de 10), esse número termina e é conhecido como um número regular . Uma expansão decimal que se repete é conhecida como repetição decimal , e os números que continuam sem repetir são números irracionais. / p>

A matemática por trás disso se aprofunda em O pequeno teorema de Fermat ... e uma vez que você começa a dizer Fermat ou teorema, torna-se um Pergunta Math.SE .

Are there numbers that are not representable in base 10 but can be represented in base 2?

A resposta é "não".

Então, neste ponto, todos devemos ter certeza de que toda expansão binária de tamanho fixo de um número racional pode ser representada como uma expansão decimal de tamanho fixo.

Deixa olhar mais de perto o decimal em C # que nos leva a Ponto flutuante decimal no .NET e dado o autor, eu aceito que é assim que funciona.

The decimal type has the same components as any other floating point number: a mantissa, an exponent and a sign. As usual, the sign is just a single bit, but there are 96 bits of mantissa and 5 bits of exponent. However, not all exponent combinations are valid. Only values 0-28 work, and they are effectively all negative: the numeric value is sign * mantissa / 10exponent. This means the maximum and minimum values of the type are +/- (296-1), and the smallest non-zero number in terms of absolute magnitude is 10-28.

Apontarei imediatamente que, devido a essa implementação, há números no tipo double que não podem ser representados em decimal - aqueles que estão fora do intervalo. Double.Epsilon é 4.94065645841247e-324 , que não pode ser representado em decimal , mas pode em double .

No entanto, dentro do intervalo que o decimal pode representar, ele tem mais bits de precisão do que outros tipos nativos e pode representá-los sem erros.

Existem alguns outros tipos por aí. Existe um BigInteger em C # que pode representar um número inteiro arbitrariamente grande. Não há equivalente ao BigDecimal do Java (que pode representar números com dígitos decimais de até 2 32 dígitos de comprimento - o que é um intervalo considerável) exatamente . No entanto, se você pesquisar um pouco , poderá encontrar implementações manuais implementadas.

Existem alguns idiomas que também têm um tipo de dados racional que permite representar exatamente os racionais (para que 1 / 3 é na verdade 1/3).

Especificamente para o C # e para a escolha do float ou do racional, eu irei adiar para Jon Skeet da pinta flutuante decimal em. NET :

Most business applications should probably be using decimal rather than float or double. My rule of thumb is that manmade values such as currency are usually better represented with decimal floating point: the concept of exactly 1.25 dollars is entirely reasonable, for example. For values from the natural world, such as lengths and weights, binary floating point types make more sense. Even though there is a theoretical "exactly 1.25 metres" it's never going to occur in reality: you're certainly never going to be able to measure exact lengths, and they're unlikely to even exist at the atomic level. We're used to there being a certain tolerance involved.

    
por 25.04.2014 / 17:38
fonte
6

Depois de sair do intervalo de valores aceitáveis, a resposta é sim. Dito isto, quase tudo dentro do intervalo terá uma representação. Referência decimal C # Embora não esteja indicado na especificação, os números irracionais não pode ser representado exatamente (por exemplo, e 1 , pi, raiz quadrada de 2, etc.).

The decimal keyword denotes a 128-bit data type. Compared to floating-point types, the decimal type has a greater precision and a smaller range, which makes it suitable for financial and monetary calculations. The approximate range and precision for the decimal type are shown in the following table.

Precision: 28-29 significant digits

1 Obrigado ao MichaelT por me lembrar de outro número irracional.

    
por 25.04.2014 / 17:35
fonte
1

Um tipo de ponto flutuante de base dois seria capaz de representar com precisão muitos valores que um tipo de base dez do mesmo tamanho não poderia. Qualquer valor que seria exatamente representável por um tipo de base-2 de algum tamanho seria exatamente representável em um tipo de base dez de tamanho suficiente. O tamanho necessário para um tipo puramente baseado em dez representar todos os valores de um número binário de ponto flutuante dependeria do intervalo expoente do tipo binário; centenas de bits para um float ou milhares para um double .

Dito isto, o tipo Decimal é grande o suficiente para que seja possível utilizá-lo como um tipo "universal" capaz de manter o valor de qualquer outro primitivo numérico e fornecer algumas outras características adicionais além disso (se nada mais, use um bit para indicar se o valor armazenado é o resultado da conversão de double e, se esse bit estiver definido, use 64 bits para manter o valor em questão). A Microsoft optou por não fazer isso, no entanto. Como resultado, a conversão de um double para Decimal falhará completamente para valores grandes, fará com que valores pequenos sejam arredondados para o 1E-28 mais próximo. Além disso, mesmo dentro do intervalo dinâmico de decimal , o método de conversão não será "round-trip". Por exemplo, avaliar 1.0 / 3.0 como duplo produzirá 0.3333333333333333148, mas convertê-lo em decimal produzirá 0.333333333333333m e convertê-lo de volta para o dobro produzirá 0.3333333333333329818.

    
por 25.04.2014 / 19:30
fonte