Voici la clé de votre dilemme: 10
le produit de 2
et 5
. Vous pouvez représenter n’importe quel nombre exactement en décimales base 10, c’est k * 1/2 n * 1/5 m où k
, n
et m
sont des entiers.
Autrement dit - si le nombre n
dans 1 / n contient un facteur qui ne fait pas partie des facteurs de la base, le nombre ne pourra pas être représenté exactement par un nombre fixe de chiffres dans le développement binaire / décimal / quel que soit nombre - il aura une partie répétitive. Par exemple, 1/15 = 0,0666666666 .... car 3 (15 = 3 * 5) n'est pas un facteur de 10.
Ainsi, tout ce qui peut être représenté en base 2 exactement (k * 1/2 n ) peut être représenté en base 10 exactement.
Au-delà de cela, il y a la question du nombre de chiffres / bits que vous utilisez pour représenter le nombre. Il y a des nombres qui peuvent être représentés exactement dans une base, mais cela prend plus qu'un certain nombre de chiffres / bits à faire.
En binaire, le nombre 1/10, qui est commodément 0,1 en décimal, ne peut pas être représenté par un nombre pouvant être représenté par un nombre fixe de bits en binaire. Au lieu de cela, le nombre est 0.00011001100110011 ... 2 (avec la partie 0011 répétée pour toujours).
Regardons le numéro 1 2 /1010 2 un peu plus près.
____
0.00011
+ ---------
1010 | 1,00000
0
-
dix
0
----
1 00 --------- +
0 |
----- |
1 000 |
0 |
------ | en répétant
1 0000 | bloc
1010 |
------ |
1100 |
1010 |
---- |
100 ---- +
C'est exactement le même type de chose que vous obtenez lorsque vous essayez de faire la division longue pour 1/3.
1/10, lorsque factorisé vaut 1 / (2 1 * 5 1 ). Pour la base 10 (ou tout multiple de 10), ce numéro se termine et est appelé un nombre normal . Une expansion décimale qui se répète est appelée décimale répétitive et les nombres qui durent indéfiniment sans se répéter sont des nombres irrationnels.
Le calcul derrière ce Delves dans le petit théorème de Fermat ... et une fois que vous commencez à dire Fermat ou théorème, il devient une question Math.SE .
Y a-t-il des nombres qui ne sont pas représentables en base 10 mais qui peuvent être représentés en base 2?
La réponse est non'.
Donc, à ce stade, nous devrions tous être clairement conscients que tout développement binaire de longueur fixe d’un nombre rationnel peut être représenté par un développement décimal de longueur fixe.
Permet de regarder de plus près à la décimale en C # qui nous amène à virgule flottante décimal dans .NET et étant donné l'auteur, j'accepte que thats comment ça marche.
Le type décimal a les mêmes composants que tout autre nombre à virgule flottante: une mantisse, un exposant et un signe. Comme d'habitude, le signe n'est qu'un bit, mais il y a 96 bits de mantisse et 5 bits d'exposant. Cependant, toutes les combinaisons d’exposants ne sont pas valides. Seules les valeurs de 0 à 28 fonctionnent et elles sont toutes négatives: la valeur numérique est . Cela signifie que les valeurs maximales et minimales du type sont +/- (2 96 -1) et que le plus petit nombre non nul en termes de magnitude absolue est 10 -28 .sign * mantissa / 10exponent
Je ferai remarquer tout de suite que, du fait de cette mise en œuvre, il y a des nombres dans le double
type qui ne peuvent pas être représentés decimal
- ceux qui sont hors de portée. Double.Epsilon
est 4.94065645841247e-324
ce qui ne peut pas être représenté dans un decimal
, mais peut dans un double
.
Toutefois, dans la plage que peut représenter le nombre décimal, il a plus de bits de précision que les autres types natifs et peut les représenter sans erreur.
Il y a d'autres types qui circulent. Il existe un BigInteger dans C # qui peut représenter un entier arbitrairement grand. Il n'y a pas d' équivalent à Java BigDecimal (qui peut représenter des nombres avec décimales jusqu'à 2 32 chiffres longs - ce qui est une gamme importante) exactement . Cependant, si vous fouillez un peu, vous pouvez trouver des implémentations roulées à la main.
Certaines langues ont aussi un type de données rationnel qui vous permet de représenter exactement les rationnels (donc 1/3 est égal à 1/3).
Spécifiquement pour C # et le choix de float ou rationnel, je laisserai la parole à Jon Skeet de la pinte flottante Decimal dans .NET :
La plupart des applications métier devraient probablement utiliser des valeurs décimales plutôt que des valeurs flottantes ou doubles. Ma règle empirique est que les valeurs artificielles telles que la monnaie sont généralement mieux représentées avec une virgule flottante décimale: le concept d’exactement 1,25 dollar est tout à fait raisonnable, par exemple. Pour les valeurs du monde naturel, telles que les longueurs et les poids, les types à virgule flottante binaire ont plus de sens. Même s'il existe un "exactement 1,25 mètre" théorique, cela ne se produira jamais: vous ne pourrez certainement jamais mesurer les longueurs exactes, et il est peu probable qu'elles existent même au niveau atomique. Nous sommes habitués à une certaine tolérance.