12
votes

Comment les langages de programmation gèrent-ils un nombre énorme nombre arithmétique

Pour un ordinateur travaillant avec un processeur 64 bits, le plus grand nombre qu'il peut gérer serait 2 64 = 18 446 744,073 709 551.616. Comment les langages de programmation, disent java ou être c, C ++ gérer l'arithmétique de nombres supérieurs à cette valeur. Tout registre ne peut pas le tenir comme une seule pièce. Comment cette question a-t-elle été abordée?


3 commentaires

Est-ce une question sur les gros entiers ou sur la manière dont les nombres de points flottants sont représentés?


Nombres entiers juste pour obtenir le concept juste comme pour l'instant :)


J'ai posé une question similaire et j'ai finalement trouvé mon chemin ici; Stackoverflow.com/Questtions/1218149/... Bonne chasse!


9 Réponses :


0
votes

En général, la langue elle-même ne gère pas l'arithmétique grand nombre de grandes précision de haute précision. Il est beaucoup plus probable que une bibliothèque est écrite qui utilise des méthodes numériques alternatives pour effectuer les opérations souhaitées.

Par exemple (je fais juste cela en ce moment), une telle bibliothèque peut imiter les techniques réelles que vous pourriez utiliser pour effectuer ce nombre grand nombre arithmétique à la main. Ces bibliothèques sont généralement beaucoup plus lentement que d'utiliser l'arithmétique intégrée, mais parfois la précision et la précision supplémentaires sont appelées.


3 commentaires

OK, cependant, lorsque cela revient aux opérations arithmétiques, disons ajouter les deux grands nombres, les deux doivent être dans des registres, pour lesquels la taille du registre ne suffit pas. Comment ce problème est-il abordé?


Vous pouvez effectuer une seule grande opération arithmétique en effectuant beaucoup de plus petits. Je pense que je l'ai dit assez clairement dans le deuxième paragraphe ...


Vous n'ajoutez pas 123098712380714091823 à 120497235897345089273403 sur un morceau de papier tout à la fois, n'est-ce que? Vous effectuez de nombreuses opérations plus petites une à la fois.



2
votes

Vous supposez la mauvaise chose. Le plus gros numéro qu'il peut gérer dans un seul registre est un numéro de 64 bits. Cependant, avec certaines techniques de programmation intelligentes, vous pouvez simplement combiner quelques dizaines de ces numéros de 64 bits d'affilée pour générer un énorme nombre de 6400 bits et utiliser cela pour effectuer plus de calculs. Il n'est tout simplement pas aussi rapide que d'avoir le numéro en forme dans un registre.

Même les anciens processeurs de 8 et 16 bits utilisaient cette astuce, où ils laisseraient simplement déborder sur d'autres registres. Cela rend les maths plus complexes mais cela ne met pas fin aux possibilités.

Cependant, une telle mathématique de haute précision est extrêmement inhabituelle. Même si vous souhaitez calculer l'ensemble de la dette nationale des États-Unis et stocker le résultat en dollars zimbabwéens, un entier de 64 bits serait toujours assez grand, je pense. Il est certainement assez grand pour contenir la quantité de mon compte d'épargne, cependant.


3 commentaires

pas vrai ... c'est surtout la partie fractionnée dont ils ne veulent pas aller plus vite (par exemple lors de l'utilisation de points de points flottants normauxD)


@Reinier, Donald Knuth a écrit plusieurs bons livres et articles sur ce sujet et informatique et mathématiques en général. Je vous suggère de commencer à lire certaines de celles-ci. De nombreuses langues ont une bibliothèque spéciale Bignum, qui peut être mise en œuvre de plusieurs manières. (Voir EN.Wikipedia.org/wiki/bignum )


Pas inhabituel .. hmm qu'en est-il .. disons que je veux 35! .. qui traverse la limite facilement



0
votes

comme une expérience de pensée, imaginez les chiffres stockés comme une chaîne. Avec des fonctions pour ajouter, multiplier, etc. Ces nombres arbitrairement longs.

En réalité, ces chiffres sont probablement stockés de manière plus respectueuse de l'espace.


0 commentaires

0
votes

Pensez à un numéro de taille de la machine comme chiffre et appliquez l'algorithme de multi-chiffres multiples à partir de l'école primaire. Ensuite, vous n'avez pas besoin de garder l'ensemble des chiffres dans des registres, juste les chiffres tels qu'ils sont travaillés.


0 commentaires

7
votes

Il y a beaucoup de techniques spécialisées pour effectuer des calculs sur des nombres plus grands que la taille du registre. Certains d'entre eux sont décrits dans cet article de Wikipedia sur arithmétique de précision arbitraire

Langues de faible niveau, telles que C et C ++, laissez des calculs de nombres volumineux à la bibliothèque de votre choix. Un notable est le bibliothèque multi-précision GNU . Des langages de haut niveau comme Python, et d'autres, l'intégrent dans le cœur de la langue, des nombres si normaux et de très grands nombres sont identiques au programmeur.


0 commentaires

0
votes

La plupart des langues les stockent comme une matrice d'entiers. Si vous ajoutez / soustrayez deux à ces gros chiffres, la bibliothèque ajoute / soustrait tous les éléments entier dans le tableau séparément et gère les pièces / emprunques. C'est comme une addition manuelle / soustraction à l'école car c'est comme ça que cela fonctionne en interne.

Certaines langues utilisent des chaînes de texte réelles au lieu de tableaux entier moins efficaces mais plus simples à transformer en une représentation de texte.


0 commentaires

1
votes

ADA soutient réellement cela de manière native, mais uniquement pour ses constantes sans faille ("Noms nommés"). Pour les variables réelles, vous devez aller trouver un emballage arbitraire. Voir Entier de longueur arbitraire dans Ada


2 commentaires

+1 Intéressant de vous voir sur, t.e.d.


Je viens de remarquer que ADA a soutenu cela comme une lecture intégrée ailleurs, mais ne savait pas que c'était limité aux constantes. C'est un peu étrange. Pouvez-vous même prendre une constante Bignum + un petit Int et vous retrouver avec un résultat de Bignum?



1
votes

plus ou moins de la même manière que vous faire. À l'école, vous avez mémorisé une addition à un chiffre, une multiplication, une soustraction et une division à une seule chiffre. Ensuite, vous avez appris à faire des problèmes à plusieurs chiffres en tant que séquence de problèmes à un chiffre.

Si vous le souhaitez, vous pouvez multiplier deux nombres à vingt chiffres ensemble en utilisant rien de plus que la connaissance d'un simple algorithme et les tables de temps à un chiffre.


1 commentaires

C'est vrai, aussi loin que ça va. Cependant, cela ne tire que les bases mêmes: l'addition, la soustraction, la multiplication et la division ne sont que le début. Ensuite, à des chiffres vraiment arbitraires, vous devez vous inquiéter de racines carrées, de suivi de précision, etc. C'est pourquoi je pense que chaque langue devrait fournir une bonne implémentation complète en standard.



2
votes

Les langages de programmation qui traitent des nombres vraiment massives utilisent des primitives de numéro personnalisées qui vont au-delà des opérations normales optimisées pour les processeurs 32, 64 ou 128 bits. Ces chiffres sont particulièrement utiles dans la sécurité informatique et la recherche mathématique.

the GNU multiple de précision est probablement le plus complet Exemple de ces approches.

Vous pouvez gérer des nombres plus grands à l'aide de tableaux. Essayez ceci dans votre navigateur Web. Tapez le code suivant dans la console JavaScript de votre navigateur Web:

Le point sur lequel JavaScript échoue xxx

JavaScript pas gérer les entiers simples ci-dessus 9999999999999998 . Mais écrire votre propre numéro primitif consiste à faire ce travail de calcul est assez simple. Voici un exemple en utilisant une classe d'additionnelle de numéro personnalisée dans JavaScript . < p> passer du test à l'aide d'une classe de numéro personnalisée xxx

comment ça marche

vous Peut regarder dans le code à Num {... } pour voir les détails de ce qui se passe; Mais voici un contour de base de la logique utilisée:

classes:

  • La classe num contient un tableau de classes numériques .
  • La classe chiffre contient la valeur d'un chiffre à un seul chiffre et la logique pour gérer le drapeau de transport

    étapes:

    1. Le numéro choisi est transformé en une chaîne
    2. Chaque chiffre est transformé en classe Classe et stocké dans la classe num en tant que tableau de chiffres
    3. Lorsque le num est incrémenté, il est effectué dans le premier chiffre dans le tableau (le plus bon nombre)
    4. Si la valeur la valeur Plus le drapeau de transport est égal à la base , puis le chiffre suivant chiffre à La gauche est appelée à être incrémentée et le nombre actuel est réinitialisé à 0
    5. ... Répétez tout le chemin vers le chiffre de gauche du tableau

      Logistiquement, il est très similaire à ce qui se passe au niveau de la machine, mais ici il est illimité. Vous pouvez En savoir plus sur la façon dont les chiffres sont porté ici ; Cela peut être appliqué aux nombres de n'importe quelle base.


0 commentaires