En JavaScript , comment obtenir:
- Le nombre entier de fois qu'un entier donné va dans un autre?
- Le reste?
En JavaScript , comment obtenir:
Pour un certain nombre y
et un certain diviseur, x
calculez le quotient ( quotient
) et le reste ( remainder
) comme:
var quotient = Math.floor(y/x);
var remainder = y % x;
3.5 % 2
évalue à 1,5. Assurez-vous de gérer (parseInt, sol, etc.) comme requisfloor
et%
ensemble n'est pas cohérent de cette façon. Soit utiliser à latrunc
place defloor
(permettant ainsi des restes négatifs) ou utiliser la soustraction pour obtenir le reste (rem = y - div * x
).rem
toute façon, vous pouvez obtenir le quotientdiv
plus rapidement , sans revêtement de sol:(y - rem) / x
. 2. Au fait, l'opération modulo par la définition recommandée de Donald Knuth (signe-correspond-diviseur, pas le reste c'est-à-dire module euclidien, ni le signe-correspond-dividende JavaScript) est ce que nous pouvons coder en JavaScript commefunction mod (a, n) { return a % n + (Math.sign(a) !== Math.sign(n) ? n : 0); }
.Je ne suis pas un expert des opérateurs au niveau du bit, mais voici une autre façon d'obtenir le nombre entier:
Cela fonctionnera également correctement pour les nombres négatifs, tandis que
Math.floor()
en arrondissant dans la mauvaise direction.Cela semble également correct:
la source
a/b | 0
~~int
,int | 0
etint >> 0
ne modifie pas l'argument initial, mais oblige l'interpréteur à passer la partie intégrante à l'opérateur.floor
à peine dans la mauvaise direction, étant donné son nom - mais pas dans la direction que les gens veulent généralement!a = 12447132275286670000; b = 128
Math.floor(a/b)
->97243220900677100
et~~(a/b)
->-1231452688
.~~(5/2) --> 2
comme le fait(5/2)>>0 --> 2
, mais~~(5/2) + 1 --> 3
, tout~~(5/2)>>0 + 1 --> 1
.~~
est un bon choix car la priorité est plus appropriée.J'ai fait des tests de vitesse sur Firefox.
Ce qui précède est basé sur 10 millions d'essais pour chacun.
Conclusion: utilisez
(a/b>>0)
(ou(~~(a/b))
ou(a/b|0)
) pour obtenir un gain d'efficacité d'environ 20%. Gardez également à l'esprit qu'ils sont tous incompatibles avecMath.floor
, quanda/b<0 && a%b!=0
.la source
Math.floor
les autres fonctions de l'API et qui sait qui, ou en savoir plus sur l'~
opérateur (bit à bit) et sur le fonctionnement des opérations bit à bit dans JS, puis comprendre l'effet du double tilde?Math.floor
mieux. Et même si ce n'est pas le cas, celui-ci est googleable.ES6 introduit la nouvelle
Math.trunc
méthode. Cela permet de corriger la réponse de @ MarkElliot pour qu'elle fonctionne également pour les nombres négatifs:Notez que les
Math
méthodes ont l'avantage sur les opérateurs au niveau du bit qu'elles fonctionnent avec des nombres supérieurs à 2 31 .la source
18014398509481984 == 18014398509481985
,.~~(x/y)
. Besoin de prendre en charge de plus grands nombres jusqu'à 54 bits signés? Utilisez-leMath.trunc
si vous l'avez, ouMath.floor
autrement (corrigez les nombres négatifs). Besoin de prendre en charge des nombres encore plus importants? Utilisez une grande bibliothèque de nombres.divmod
, vous pouvez l'implémenter comme tel:function divmod(x, y) { var div = Math.trunc(x/y); var rem = x % y; return [div, rem]; }
la source
Math.trunc
:). J'ai vérifié avec 100,3; -100,3; 100, -3 et -100, -3. Bien sûr, beaucoup de temps s'est écoulé depuis votre commentaire et les choses changent.J'utilise normalement:
Ce n'est probablement pas le plus élégant, mais ça marche.
la source
Vous pouvez utiliser la fonction
parseInt
pour obtenir un résultat tronqué.Pour obtenir un reste, utilisez l'opérateur mod:
parseInt a quelques pièges avec les chaînes, pour éviter d'utiliser le paramètre radix avec la base 10
Dans certains cas, la représentation sous forme de chaîne du nombre peut être une notation scientifique, dans ce cas, parseInt produira un résultat incorrect.
Cet appel produira 1 comme résultat.
la source
parseInt
doit être évité autant que possible. Voici l'avertissement de Douglas Crockford: "Si le premier caractère de la chaîne est 0, alors la chaîne est évaluée en base 8 au lieu de base 10. En base 8, 8 et 9 ne sont pas des chiffres, donc parseInt (" 08 ") et parseInt ("09") produit 0 comme résultat. Cette erreur provoque des problèmes dans les programmes qui analysent les dates et les heures. Heureusement, parseInt peut prendre un paramètre radix, de sorte que parseInt ("08", 10) produit 8. Je vous recommande de toujours fournir le paramètre radix. " archive.oreilly.com/pub/a/javascript/excerpts/…parseInt
faut éviter; juste qu'il y a quelques pièges à connaître. Vous devez être conscient de ces choses et être prêt à y faire face.parseInt
avec un argument numérique.parseInt
est censé analyser des chaînes partiellement numériques, pas tronquer des nombres.JavaScript calcule à droite le plancher des nombres négatifs et le reste des nombres non entiers, en suivant les définitions mathématiques pour eux.
FLOOR est défini comme "le plus grand nombre entier inférieur au paramètre", ainsi:
REMAINDER est défini comme le «reste» d'une division (arithmétique euclidienne). Lorsque le dividende n'est pas un entier, le quotient n'est généralement pas non plus un entier, c'est-à-dire qu'il n'y a pas de reste, mais si le quotient est forcé d'être un entier (et c'est ce qui se passe lorsque quelqu'un essaie d'obtenir le reste ou le module d'un nombre à virgule flottante), il restera évidemment un "non entier".
JavaScript calcule tout comme prévu, donc le programmeur doit faire attention à poser les bonnes questions (et les gens devraient faire attention à répondre à ce qui est demandé!) La première question de Yarin n'était PAS "quelle est la division entière de X par Y", mais, au lieu de cela, "le nombre entier de fois qu'un entier donné va dans un autre". Pour les nombres positifs, la réponse est la même pour les deux, mais pas pour les nombres négatifs, car la division entière (dividende par diviseur) sera -1 inférieure à la fois où un nombre (diviseur) "entre" dans un autre (dividende). En d'autres termes, FLOOR retournera la bonne réponse pour une division entière d'un nombre négatif, mais Yarin ne l'a pas demandé!
gammax a répondu correctement, ce code fonctionne comme demandé par Yarin. D'un autre côté, Samuel a tort, il n'a pas fait le calcul, je suppose, ou il aurait vu que ça marche (aussi, il n'a pas dit quel était le diviseur de son exemple, mais j'espère que c'était le cas) 3):
Reste = X% Y = -100% 3 = -1
GoesInto = (X - Reste) / Y = (-100 - -1) / 3 = -99 / 3 = -33
Soit dit en passant, j'ai testé le code sur Firefox 27.0.1, il a fonctionné comme prévu, avec des nombres positifs et négatifs et également avec des valeurs non entières, à la fois pour le dividende et le diviseur. Exemple:
-100,34 / 3,57: GoesInto = -28, reste = -0,3800000000000079
Oui, j'ai remarqué qu'il y a un problème de précision, mais je n'ai pas eu le temps de le vérifier (je ne sais pas si c'est un problème avec Firefox, Windows 7 ou le FPU de mon CPU). Pour la question de Yarin, qui n'implique que des entiers, le code du gammax fonctionne parfaitement.
la source
Math.floor(operation)
renvoie la valeur arrondie de l'opération.Exemple de 1 ère question:
Console:
Exemple de 2 ème question:
Console:
la source
Le calcul du nombre de pages peut être effectué en une seule étape: Math.ceil (x / y)
la source
Alex Moore-NiemiCommentaire d' en réponse:
Pour les Rubyists ici de Google à la recherche de
divmod
, vous pouvez l'implémenter comme tel:Résultat:
la source
divmod
utilisations division parqueté (Math.floor
), qui diffère de la division tronquée (Math.trunc
) lorsque sont impliqués des nombres négatifs. C'est le cas du package NPMdivmod
, Rubydivmod
, SWI-Prologdivmod
et probablement de nombreuses autres implémentations.divmod
existe car il est exécuté deux fois plus vite que le calcul séparé des deux opérations. Fournir une telle fonction sans cet avantage de performance peut être déroutant.Si vous divisez simplement avec des puissances de deux, vous pouvez utiliser des opérateurs au niveau du bit:
(Le premier est le quotient, le second le reste)
la source
function divideByPowerOf2(num, exponent) { return [num >> exponent, num & ((1 << exponent) - 1)]; }
.Vous pouvez également utiliser ternaire pour décider comment gérer les valeurs entières positives et négatives.
Si le nombre est positif, tout va bien. Si le nombre est négatif, il ajoutera 1 en raison de la façon dont Math.floor gère les négatifs.
la source
Cela sera toujours tronqué vers zéro. Je ne sais pas s'il est trop tard, mais voilà:
la source
Si vous devez calculer le reste pour les très grands entiers, que le runtime JS ne peut pas représenter en tant que tels (tout entier supérieur à 2 ^ 32 est représenté comme un flottant et perd ainsi sa précision), vous devez faire un tour.
Ceci est particulièrement important pour vérifier de nombreux cas de chiffres de contrôle qui sont présents dans de nombreux cas de notre vie quotidienne (numéros de compte bancaire, cartes de crédit, ...)
Tout d'abord, vous avez besoin de votre numéro sous forme de chaîne (sinon vous avez déjà perdu la précision et le reste n'a pas de sens).
Vous devez maintenant diviser votre chaîne en parties plus petites, suffisamment petites pour que la concaténation de tout reste et un morceau de chaîne puisse tenir en 9 chiffres.
Préparez une expression régulière pour diviser la chaîne
Par exemple, si
digits
est 7, l'expression rationnelle estIl correspond à une sous-chaîne non vide de longueur maximale 7, qui est suivie (
(?=...)
est une anticipation positive) par un nombre de caractères qui est multiple de 7. Le `` g '' consiste à faire en sorte que l'expression passe à travers toute la chaîne, sans s'arrêter à la première correspondance.Maintenant, convertissez chaque partie en entier et calculez les restes par
reduce
(en ajoutant le reste précédent - ou 0 - multiplié par la puissance correcte de 10):Cela fonctionnera en raison de l'algorithme de reste "soustraction":
ce qui permet de remplacer toute «partie initiale» de la représentation décimale d'un nombre par son reste, sans affecter le reste final.
Le code final ressemblerait à:
la source