web-dev-qa-db-fra.com

Extrêmement grands nombres en javascript

Je travaille sur les problèmes du Project Euler (actuellement question 1 ).

Pour cette question, je dois trouver les 10 premiers chiffres de la somme de 100 numéros tous d'une taille similaire à ceci:

91,942,213,363,574,161,572,522,430,563,301,811,072,406,154,908,250

Je pense que je pourrais utiliser quelque chose comme BigInteger de Java, mais j'ai commencé à résoudre les problèmes en JavaScript (j'essaie de renforcer mes capacités js pour le travail), et je voudrais continuer à l'utiliser, même pour résoudre ce problème.

J'aimerais rester fidèle à JS si possible.

12
JEJoll

Vous allez avoir besoin d'une bibliothèque BigInteger basée sur javascript. Il y en a beaucoup à choisir. En voici un https://github.com/peterolson/BigInteger.js

Vous pouvez l'utiliser comme ceci

var n = bigInt("91942213363574161572522430563301811072406154908250")
    .plus("91942213363574161572522430563301811072406154908250");
13
bhspencer

Javascript a récemment obtenu un nouveau type de données primitif BigInt. https://github.com/tc39/proposal-bigint

Seulement Chrome a publié cette fonctionnalité maintenant, tandis que d'autres navigateurs l'implémentent encore. https://developers.google.com/web/updates/2018/05/bigint =

Fondamentalement, il peut être déclaré en utilisant des littéraux comme

var a = 1n;

ou

var b = BigInt('22222222222222222222222222222222');

Les opérateurs mathématiques ne font pas de conversion automatique entre BigInt et Number, donc 1 + 1n Générera une erreur.

8
Qi Fan

Vous pouvez toujours convertir votre somme en string, arracher le . et récupérez le résultat - quelque chose comme ceci:

var sum = 2384762348723648237462348;
sum = sum.toString(); // "2.3847623487236483e+24"

// Rip out the "."
sum = sum.substr(0, 1) + sum.substr(2);

// Grab the first 10 characters
var firstTen = sum.substr(0, 10);
0
Alex McMillan

Étonnamment, coller toutes les valeurs dans un tableau et les ajouter toutes ensemble et ne prendre que les 10 premiers chiffres a fonctionné. J'ai dû avoir une faute de frappe quelque part dans mon code alors qu'elle ne fonctionnait pas auparavant.

Je suis sûr que faire quelque chose d'aussi simple ne fonctionnerait pas dans tous les cas (comme ceux dont @AlexMcmillan et @zerkms ont débattu). Je pense que le pari le plus sûr est la bibliothèque BigInteger mentionnée par @bhspencer, mais il semble que l'ajout des premiers x chiffres significatifs avec y chiffres comme tampon pourrait également valoir la peine dans certains cas.

0
JEJoll

J'ai fait cela en utilisant un tableau et en mettant à jour toutes les entrées avec une fonction.

function f(a) {
  for (let i = 0; i < a.length - 1; i++) {
      a[i + 1] = a[i + 1] + parseInt(a[i] / 10);
      a[i] = a[i] % 10;
  }
  return a;
}
// remember to init the array with enough elements for all digits
var a = Array(200);
a.fill(0);
a[0] = 1;

Ici est un JSFiddle avec le code du problème 20.

0
cheesehead