Aqui está a chave para o seu dilema: 10
é o produto de 2
e 5
. Você pode representar qualquer número exatamente na base de 10 casas decimais que é k * 1/2 n * 1/5 m , onde k
, n
e m
são inteiros.
Alternativamente fraseado - se o número n
em 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 double
tipo que não podem ser representados decimal
- aqueles que estão fora do intervalo. Double.Epsilon
é 4.94065645841247e-324
que 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.