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

42

C#possui o decimaltipo usado para números que precisam de representação exata na base 10. Por exemplo, 0.1não pode ser representado na base 2 (por exemplo, floate double) e sempre será uma aproximação quando armazenado em variáveis ​​desses tipos.

Fiquei me perguntando se o fato inverso 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 (nesse caso, eu gostaria de usar um em floatvez de um decimalpara lidar com eles)?

Máx.
fonte
14
+1 à pergunta, mas a tag c # é realmente aplicável aqui? Outros idiomas também têm o tipo decimal.
Patrick M
1
@ Max: Como exercício, sugiro que você imagine converter um número de base 2 em base 10 manualmente. Por exemplo, para calcular o valor de 0.11_b2, escreva-o como 0.5 + 0.5 * 0.5. Existe alguma etapa que possa falhar ou resultar em um decimal repetido? Pessoalmente, acho que esse exercício faz um ótimo trabalho ao transmitir uma intuição sobre os números da base 2. Suponho que alguém poderia dar um passo adiante e transformar esse exercício em uma prova de construção.
Brian
Ah, mas você está errado. 1/1010
Xavier J
3
@ Ramhound Dadas as limitações de memória, o binário pode representar 0.0999999....998..exatamente, mas não o número completo 0.1- aproximações como arredondar para as centenas mais próximas 0.100são uma preocupação de implementação que envolve não mostrar todos os dígitos e arredondá-los.
Izkata
1
Bem, é possível criar um mecanismo de codificação FP que permita que '0.1' seja representado exatamente. Essa codificação simplesmente muda em torno dos conjuntos de faixas de números FP que podem e não podem ser representados.
Martin James

Respostas:

104

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

Alternativamente fraseado - se o número nem 1 / N contém um factor que não faz parte dos elementos da base, o número não serão capazes de ser representados exactamente em um número fixo de dígitos do binário / decimal / qualquer que seja a 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, qualquer coisa que possa ser representada exatamente na base 2 (k * 1/2 n ) pode ser representada 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 representados exatamente em alguma base, mas são necessários mais do que algum número de dígitos / bits.


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 para o número 1 2 /1010 2 um pouco mais de perto.

          ____                  
       0,00011                  
     + ---------                 
1010 1.00000                  
       0 0                        
       -                       
       1 0                      
         0 0                      
       ----                     
       1 00 --------- +          
          0          
       ----- |          
       1 000          
           0          
       ------ | recorrente
       1 0000 quadra    
         1010          
       ------ |          
          1100          
          1010          
          ---- |          
            100 ---- +          

Este é exatamente o mesmo tipo de coisa que você obtém ao tentar 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 número regular . Uma expansão decimal que se repete é conhecida como decimal de repetição , e os números que duram para sempre sem repetir são números irracionais.

A matemática por trás dessa investiga o pequeno teorema de Fermat ... e uma vez que você começar a dizer Fermat ou teorema, torna-se uma questão Math.SE .

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

A resposta é não'.

Portanto, neste ponto, devemos esclarecer que toda expansão binária de comprimento fixo de um número racional pode ser representada como uma expansão decimal de comprimento fixo.


Vamos olhar mais de perto o decimal em C #, que nos leva ao ponto flutuante decimal no .NET e, dado o autor, aceito que é assim que funciona.

O tipo decimal possui os mesmos componentes que qualquer outro número de ponto flutuante: uma mantissa, um expoente e um sinal. Como de costume, o sinal é apenas um bit, mas existem 96 bits de mantissa e 5 bits de expoente. No entanto, nem todas as combinações de expoentes são válidas. Somente os valores de 0 a 28 funcionam e são efetivamente todos negativos: o valor numérico é . Isso significa que os valores máximo e mínimo do tipo são +/- (2 96 -1), e o menor número diferente de zero em termos de magnitude absoluta é 10 -28 .sign * mantissa / 10exponent

Vou apontar imediatamente que, por causa dessa implementação, existem números do doubletipo que não podem ser representados decimal- aqueles que estão fora do intervalo. Double.Epsiloné 4.94065645841247e-324que não pode ser representado em um decimal, mas pode em um 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 outros tipos flutuando. Há 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 - o que é um intervalo considerável) exatamente . No entanto, se você bisbilhotar um pouco, poderá encontrar implementações feitas à mão.

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


Especificamente para C # e para a escolha de float ou racional, passarei a Jon Skeet da caneca flutuante Decimal no .NET :

A maioria dos aplicativos de negócios provavelmente deve usar decimal em vez de float ou double. Minha regra geral é que valores artificiais, como moeda, geralmente são melhor representados com ponto flutuante decimal: o conceito de exatamente 1,25 dólar é inteiramente razoável, por exemplo. Para valores do mundo natural, como comprimentos e pesos, os tipos binários de ponto flutuante fazem mais sentido. Mesmo que exista um "exatamente 1,25 metros" teórico, isso nunca ocorrerá na realidade: você certamente nunca será capaz de medir comprimentos exatos, e é improvável que eles existam no nível atômico. Estamos acostumados a haver uma certa tolerância envolvida.

Comunidade
fonte
+1 para uma explicação matemática clara e concisa. E para responder à versão mais geral da pergunta colocada no título, um exemplo de número não representável na base 10 é 1/3.
Doval
@Doval Suspeito que exista uma falha no meu raciocínio ou explicação que uma pessoa mais orientada para a matemática possa apontar ... mas acho que estou no caminho certo, se for esse o caso.
"Relativamente primo", neste caso, significa apenas "não é um fator de", certo? Falta alguma relação matemática mais profunda?
Patrick M
1
Ah, pelo que entendi, n = 15e b = 10não são relativamente primos ("não compartilham fatores positivos comuns (divisores), exceto 1")) porque compartilham 5 como um fator. A chave é que nem todos os fatores de 15 (5 e 3) também não são 10. (Além disso: existe uma palavra para indicar números que compartilham ou não todos os fatores comuns?). embrulhado em sua k, n, mequação, mas para realmente envolvê-lo, eu precisaria ver um gráfico em 3D. Independentemente, bem merecido +1 para você.
Patrick M
1
@PatrickM: "Além disso: existe uma palavra para indicar números que compartilham ou não todos os fatores comuns?": Qualquer número inteiro é um fator em si, portanto, se todos os fatores de m são fatores de n , segue-se trivialmente que m é um fator de n . Um termo para isso, como você sabe claramente, é fator . Outro é divisor .
Ruakh 26/04
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 em C # Embora não declarado na especificação, os números irracionais não podem ser representados exatamente (por exemplo, e 1 , pi, raiz quadrada de 2 etc.).

A palavra-chave decimal indica um tipo de dados de 128 bits. Comparado aos tipos de ponto flutuante, o tipo decimal possui uma precisão maior e um intervalo menor, o que o torna adequado para cálculos financeiros e monetários. O intervalo aproximado e a precisão do tipo decimal são mostrados na tabela a seguir.

Precisão: 28-29 dígitos significativos

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

Adam Zuckerman
fonte
2
@ Magus considere o número irracional e(2,71 ...). O logon natural - ln (x) é a base de logs e. Assim, bases irracionais existem e são úteis. A utilidade particular da base pi, não tenho certeza - mas isso não significa que não seja usada em algum lugar.
6
@ Max, você está se desviando cada vez mais para questões de matemática. Você pode descobrir Se um número é irracional na base 10, é irracional em outras bases? para ser uma leitura útil e um ponto de partida para mais perguntas sobre a teoria dos números.
2
1/3 não é irracional.
Adam Zuckerman
2
O OP perguntou sobre a base 10 (dez). Criar uma base do sistema numérico de qualquer coisa permitirá que você expresse qualquer coisa como 10. Com base no artigo da Wikipedia , usar um número irracional como base não a torna racional. Os números racionais podem ser expressos como números inteiros para o numerador e o denominador, repetindo números em um decimal ou terminação finita de números em um decimal.
Adam Zuckerman
5
@FrustratedWithFormsDesigner A irracionalidade não tem nada a ver com bases. Bem, isso é um exagero, mas é a irracionalidade que tem implicações para a representação do número em várias bases (por exemplo, se possui dígitos infinitos e não repetitivos), e não o contrário. Leia a pergunta math.se vinculada a acima: math.stackexchange.com/questions/625473/…
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 10 de tamanho suficiente. O tamanho exigido para um tipo puramente de base dez para representar todos os valores de um número de ponto flutuante binário dependeria do intervalo de expoente do tipo binário; centenas de bits para a floatou milhares para a double.

Dito isto, o Decimaltipo é grande o suficiente para tornar possível o uso como um tipo "universal" capaz de manter o valor de qualquer outra primitiva numérica e fornecer outros recursos adicionais além disso (se nada mais, use um bit para indicar se o valor armazenado é o resultado da conversão de a doublee, 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 doublea Decimalfalhará completamente para valores grandes, fará com que valores pequenos sejam arredondados para o 1E-28 mais próximo. Além disso, mesmo dentro da faixa dinâmica dedecimal, o método de conversão não será "ida e volta". Por exemplo, avaliar 1,0 / 3,0 como duplo produzirá 0,333333333333333314148, mas a conversão para decimal produzirá 0,33333333333333333m e a conversão de volta para duplo resultará em 0,33333333333333323218.

supercat
fonte