11
votes

Algorithme de détection de décimales répétitives?

Y a-t-il un algorithme pour déterminer les choses suivantes?

  1. Si le résultat d'une division est une décimale répétée (en binaire). Li>
  2. Si cela répète, à quel chiffre (représenté comme une puissance de 2) commence la répétition? Li>
  3. Quels chiffres répètent-ils? Li> ol>

    Quelques exemples: p>

    1/2 = 1/10 = 0.1 // 1 = false, 2 = N/A, 3 = N/A, 4 = N/A
    1/3 = 1/11 = 0.010101... // 1 = true, 2 = -2, 3 = 10
    2/3 = 10/11 = 0.101010... // 1 = true, 2 = -1, 3 = 10
    4/3 = 100/11 = 1.010101... // 1 = true, 2 = 0, 3 = 10
    1/5 = 1/101 = 0.001100110011... // 1 = true, 2 = -3, 3 = 1100
    


4 commentaires

Quelles conditions de plus avez-vous utilisées pour obtenir le résultat? Pourquoi les chiffres ne sont-ils pas répétés "01", "01", "10" et "0011"?


@Guffa Mon raisonnement était de mettre en premier lieu parce que les principaux zéros ne sont pas [significatifs] [1], tandis que les zéros traînants sont. Si le nombre était quelque chose comme "111.010101 ...", les numéros répétitifs seraient "01" car dans ce cas, le premier 0 est significatif. [1]: en.wikipedia.org/wiki/significant_digits


@Guffa (suite) qui n'est pas important pour moi. Si vous m'avez dit comment faire cela d'une manière qui a renvoyé "01", "01", "01" et "0011" Je serais heureux. :)


Sonne comme projecturer.net/problem=26 ;-)


6 Réponses :


11
votes
  1. Si le diviseur n'est pas une puissance de 2 (en général, contient des facteurs premiers non partagés avec la base de représentation)
  2. La longueur du cycle de répétition sera entraînée par le principal facteur premier du dividende (mais non connecté à la longueur de la représentation de ce facteur - voir 1/7 en décimal), mais la première longueur de cycle peut différer de la répétition unité (par exemple 11/28 = 1/4 + 1/7 en décimal).
  3. Le cycle réel dépendra du numérateur.

1 commentaires

+1 Merci pour votre commentaire. Cela me donne un aperçu du problème. En particulier l'idée que la longueur du cycle et le cycle réel sont entraînées par différents facteurs sont importantes. Je savais que cela serait important pour stocker le cycle, mais je ne considérais pas qu'il pourrait être important de calculer le cycle. Cependant, je ne vois toujours pas comment calculer les informations.



3
votes

Vérifiez expansion décimale , et spécifiquement sur la période d'une fraction.


1 commentaires

+1 Merci pour votre message. Cela m'a aidé à comprendre le problème.



8
votes

Je peux donner un indice - répéter des décimales à la base dix sont toutes des fractions avec le dénominateur ayant au moins un facteur privilégié que deux et cinq. Si le dénominateur ne contient aucun facteur privilégié deux ou cinq, ils peuvent toujours être représentés avec un dénominateur de tous les nés. Ensuite, le nominateur est la partie répétée et le nombre de nines est la longueur de la partie répétée.

                                                     __
 1/3            =  1/(2^2-1) =        1/11       = 0.01
                                                     __
 2/3            =  2/(2^2-1) =       10/11       = 0.10
                       __
 4/3  => 1 + 1/3 =>  1.01
                       __
10/3  => 3 + 1/3 => 11.01
                                                     ____
 1/5  =   3/15  =  3/(2^4-1) =       11/1111     = 0.0011
                                                     ________
11/17 = 165/255 = 11/(2^8-1) = 10100101/11111111 = 0.10100101


1 commentaires

+1 Par cette logique, à la base 2, les décimales répétées sont des fractions avec des dénominateurs ayant des facteurs primaires autres que 2 (je le savais). Je ne savais pas que s'ils avaient un facteur premier 1, il a commencé quelque part autre que la première position (c'est une information utile!).



5
votes

Tout d'abord, l'un de vos exemples est faux. La partie répétitive de 1/5 est 0011 plutôt que 1100 , et commence au tout début de la partie fractionnée.

Une décimale répétée est quelque chose comme:

A / B = C + D (2 -n + 2 -nk + 2 -n-2k +. ..)
= C + 2 -n * d / (1 - 2 -k )

dans lequel n et d sont ce que vous voulez.

Par exemple,

1/10 (déc) = 1/1010 (bin) = 0.0001100110011 ... // 1 = vrai, 2 = -1, 3 = 0011

pourrait être représenté par la formule avec

a = 1, b = 10 (déc) , c = 0, d = 0,0011 (bin) , n = 1, k = 4;
(1 - 2 -k ) = 0,1111

Par conséquent, 1/10 = 0,1 * 0,0011 / 0.1111 . La partie clé d'une représentation décimale répétée est générée en divisant par (2 n - 1) ou son tout multiple de 2. Vous pouvez donc trouver un moyen d'exprimer votre le dénominateur en tant que tel (comme la construction de tables constantes) ou une division de gros chiffre (qui est relativement lente) et trouvez la boucle. Il n'y a pas de moyen rapide de le faire.


2 commentaires

+1 pour votre entrée technique. Cependant, la méthode de Guffa semble assez efficace et semble être linéaire par rapport à la longueur du nombre, qui est suffisamment rapide, étant donné que cela sera probablement utilisé le plus souvent avec des nombres plus petits. Bien que cela me permet de prendre en charge les opérations de points flottantes de précision arbitraire, le but réel est de garder la base 10 numéros précis (c'est-à-dire dans la plupart des langues 1.1 base 10 sort 1.100000001 ou somesuch à cause de décimales répétées).


En fait, il y a de meilleures façons de donner à votre objectif: vous pouvez garder des nombres rationnels sous forme de fraction au lieu de les développer, ou vous pouvez simplement faire les mathématiques à base de base 10. Le traitement des décimales répétées n'est pas assez facile comme je l'imagine. :)



1
votes

Pour trouver le motif de répétition, gardez simplement une trace des valeurs que vous utilisez le long de la ligne:

.1
No repeat.
.01
Repeat from digit -1 length 2.
.10
Repeat from digit -1 length 2.
1.0
Repeat from digit 0 length 2.
.0011
Repeat from digit -1 length 4.


3 commentaires

Je ne sais pas si cela résout son problème, car certaines fractions se répètent après un certain nombre de chiffres par exemple 5/6 = .8333333. Donc, sous votre modèle, il utiliserait le 8 pour trouver une répétition.


@letseatchunch: 5/6 = 101/110 = 0.1101010101010101010 ... Si vous exécutez FINDPATTERN (5,6), il trouvera le motif à répéter du chiffre -2 avec la longueur 2.


Il m'a fallu un peu de temps pour comprendre votre code parce que je ne sais pas très bien c #, mais je pense que c'est exactement pour ce que je cherchais. J'écris ceci en C ++ et le stockage de chiffres n'est pas exactement de cette façon, mais il devrait être assez facile de le porter. Merci beaucoup pour votre aide!



2
votes

Vous pouvez faire un Division longue , notant les restes. La structure des restes vous donnera la structure de tout décimal rationnel :

  1. Le dernier reste est zéro: c'est une décimale sans une partie répétée
  2. Le premier et le dernier reste sont égaux: la décimale se répète juste après le point
  3. La distance entre le premier et le premier reste égal aux derniers sont les chiffres non répétés, le reste est la partie répétée

    En général, les distances vous donneront la quantité de chiffres pour chaque partie.

    Vous pouvez voir cet algorithme codé dans C ++ dans la méthode décompose () ici .

    Essayez 228142 / 62265 , il a une période de 1776 chiffres!


0 commentaires