Division entière avec reste en JavaScript?
En JavaScript, comment puis-je obtenir:
- le nombre entier de fois un nombre entier donné va dans une autre?
- le reste?
Vous devez vous connecter pour publier un commentaire.
En JavaScript, comment puis-je obtenir:
Vous devez vous connecter pour publier un commentaire.
Pour un certain nombre
y
et certains diviseurx
calculer le quotient (quotient
) et le reste (remainder
) comme:3.5 % 2
évalue à 1,5. Assurez-vous de la poignée (parseInt, plancher, etc.) comme l'exigefloor
et%
ensemble n'est pas cohérent dans ce sens. Soit utilisertrunc
au lieu defloor
(ce qui permet de négatif restes) ou d'utiliser la soustraction pour obtenir le reste (rem = y - div * x
).Math.floor()
ici, c'est juste pour le cas que nombre donné sont positifs. regardez ce pour plus d'explication. NormalementparseInt()
est mieux de choisir d'obtenir la partie entière d'un nombre ou une chaîne.rem
de toute façon, vous pouvez obtenir le quotientdiv
plus vite, sans plancher:(y - rem) / x
. 2. Par la façon dont le modulo par Donald Knuth est recommandé définition (signe-correspond-diviseur, pas le reste, c'est à dire Euclidienne module, ni le JavaScript signe-correspond-dividende) est ce que l'on peut coder en JavaScript commefunction mod (a, n) { return a % n + (Math.sign(a) !== Math.sign(n) ? n : 0); }
.quotient * divisor + remainder = dividend
vrai, le quotient est à l'étage.-9 % 2
est-1
au lieu de1
.Je ne suis pas expert dans les opérateurs au niveau du bit, mais voici une autre façon d'obtenir le nombre entier:
Cela fonctionne correctement pour les nombres négatifs, tandis que
Math.floor()
rond dans la mauvaise direction.Cela semble correct ainsi:
a/b | 0
~~int
,int | 0
etint >> 0
ne pas modifier argument initial, mais assurez-interprète pass partie intégrante de l'opérateur.floor
à peine tours dans la mauvaise direction, compte tenu de son nom tout simplement pas le sens que les gens veulent généralement bien!a = 12447132275286670000; b = 128
Math.floor(a/b)
->97243220900677100
et~~(a/b)
->-1231452688
.~~(5/2) --> 2
comme(5/2)>>0 --> 2
, mais~~(5/2) + 1 --> 3
, tandis que~~(5/2)>>0 + 1 --> 1
.~~
est un bon choix parce que la priorité est plus approprié.>>0
est pourquoi emscripten et asm.js utilisation|0
Math.floor
lorsque les numéros d'aller au-delà de 53 bits... C'est juste les limites inhérentes à présent partout dans l'endroit. Si vous voulez faire cela pour arbitrairement grand nombre, vous avez besoin de quelques bigint / bignumber de la bibliothèque.Math.floor
tours, le négatif quotient dans le mal, mais plutôt dans un différentes direction.Math.floor(-3 / 10) === -1
serait alors correspondent à parqueté division (tours "vers le bas"), alors que~~(-3 / 10) === 0
correspond à tronquée de la division (tours "vers zéro"). Voir Wiki: Modulo.Math.floor
ou la nouvelleMath.trunc
de ES6 Edge (12+)| 0
à tronquer, en particulier en raison de son utilisation dans asm.js, de sorte que vous ne pouvez pas vraiment dire qu'il code le code, parce que son sens est déjà largement connu.|0
. Aussi, il est sans importance que asm.js utilise un style spécifique, car il n'est pas censé être écrit/lu par des humains, mais par transpilers et navigateurs~~
ou| 0
n'a pas déjà utilement existe pas, quelqu'un pourrait avoir été tenté d'ajouter. Comme Joel a dit, "Ancien code ne rouille pas". N'employez pas utile conventions existantes, tout simplement parce qu'ils sont vieux. C'est Une Bonne idée.J'ai fait quelques tests de vitesse sur Firefox.
Ci-dessus est basé sur les 10 millions d'essais pour chaque.
Conclusion: Utilisation
(a/b>>0)
(ou(~~(a/b))
ou(a/b|0)
) pour atteindre environ 20% de gain d'efficacité. Aussi garder à l'esprit qu'ils sont tous incompatibles avecMath.floor
, quanda/b<0 && a%b!=0
.Math.floor
et qui-sait-comment-et de nombreuses autres fonctions de l'API ou de l'apprentissage,~
(au niveau du bit-non) de l'opérateur et de la façon dont les opérations bit à bit de travail en JS et ensuite comprendre l'effet de la double tilde?Math.floor
mieux. Et même si non, c'est googleable.ES6 présente le nouveau
Math.trunc
méthode. Cela permet de fixer @MarkElliot réponse pour le faire fonctionner pour les nombres négatifs trop:Noter que
Math
méthodes ont l'avantage sur les opérateurs au niveau du bit qu'ils travaillent avec les numéros de plus de 231.18014398509481984 == 18014398509481985
.18014398509481984 / 5
est3602879701896396.8
. Toutefois, ne peuvent pas être stockés, de sorte qu'il est converti3602879701896397
. Et puisMath.trunc(3602879701896397)
est3602879701896397
.~~(x/y)
. Besoin d'un soutien plus grand des nombres jusqu'à 54 bits signé? UtilisationMath.trunc
si vous l'avez, ouMath.floor
sinon (bon pour les nombres négatifs). Besoin d'un soutien encore plus grand nombre? L'utilisation de certains grand nombre de la bibliothèque.divmod
, vous pouvez la mettre en œuvre en tant que telle:function divmod(x, y) { var div = Math.trunc(x/y); var rem = x % y; return [div, rem]; }
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.Vous pouvez utiliser la fonction
parseInt
pour obtenir un résultat tronqué.À obtenir un reste, l'utilisation de mod de l'opérateur:
parseInt ont certains pièges avec des cordes, pour éviter d'utiliser un paramètre radix avec la base 10
Dans certains cas, la représentation de chaîne de la valeur peut être une forme de notation scientifique, dans ce cas, parseInt va produire un résultat erroné.
Cet appel va produire 1 comme résultat.
parseInt
devrait être évitée lorsque cela est possible. Voici Douglas Crockford de l'avertissement: "Si le premier caractère de la chaîne est 0, alors la chaîne est évaluée dans la base de 8 au lieu de la base 10. En base 8, 8 et 9 ne sont pas des chiffres, parseInt("08") et parseInt("09") produisent des 0 comme leur 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
doit être évité; juste qu'il y a quelques astuces à connaître. Vous devez être au courant de ces choses et être prêts à faire face.parseInt
avec un argument nombre.parseInt
est censé analyser partiellement des chaînes numériques, de ne pas tronquer des nombres.JavaScript calcule la droite de la chaussée des nombres négatifs et le reste des nombres non-entiers, à la suite de la définition mathématique pour eux.
SOL est définie comme "le plus grand nombre entier plus petit que le paramètre", donc:
RESTE est définie comme la "gauche" de la division (Euclidienne de l'arithmétique). Lorsque le dividende n'est pas un entier, le quotient est généralement pas un nombre entier, c'est à dire, il n'y a pas de reste, mais si le quotient est forcé à être un nombre entier (et c'est ce qui arrive quand quelqu'un essaie de faire le reste ou le module d'un nombre à virgule flottante), il y aura un non-entier "de gauche " de plus", évidemment.
JavaScript ne calcule tout comme prévu, le programmeur doit faire attention à poser les bonnes questions (et les gens devraient être attentif à répondre à ce qui est demandé!) Yarin est de la première question n'était PAS "qu'est-ce que la division entière de X par Y", mais, au contraire, "le nombre ENTIER de fois un nombre entier donné VA DANS une autre". Pour les nombres positifs, la réponse est la même pour les deux, mais pas pour les nombres négatifs, parce que la division entière (dividende par le diviseur) sera -1 plus petit que la fois d'un nombre (diviseur) "va dans" de l'autre (dividende). En d'autres termes, le PLANCHER sera de retour la réponse correcte pour une division entière d'un nombre négatif, mais Yarin n'ai pas demandé que!
gammax répondu correctement, que le code fonctionne comme demandé par Yarin. D'autre part, Samuel est faux, il n'a pas les maths, je suppose, ou il aurait vu qu'il ne fonctionne pas (d'ailleurs, il n'a pas dit quel était le diviseur de son exemple, mais j'espère que ça a été 3):
Reste = X % Y = -100 % 3 = -1
GoesInto = (X - Reste) /Y = (-100 - -1) /3 = -99 /3 = -33
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 aussi avec les 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é, il y a un problème de précision de là, 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 avec mon CPU FPU). Pour Yarin la question, pourtant, qui n'implique que des nombres entiers, les gammax code fonctionne parfaitement.
Math.floor(operation)
retourne l'arrondi de la valeur de l'opération.Exemple de la 1st question:
Console:
Exemple de la 2ème question:
Console:
Que j'utilise habituellement:
C'est probablement pas le plus élégant, mais il fonctionne.
Alex Moore-Niemis'commentaire comme une réponse:
Pour Rubyists ici de Google dans la recherche de
divmod
, vous pouvez la mettre en œuvre en tant que telle:Résultat:
divmod
utilise parqueté division (Math.floor
), qui diffère de l'tronquée de la division (Math.trunc
) lorsque les nombres négatifs sont impliqués. C'est le cas pour NPMdivmod
paquet, Rubydivmod
, SWI-Prologdivmod
et sans doute beaucoup d'autres implémentations, trop.divmod
existe parce qu'il est effectue deux fois plus rapide que le calcul de ces deux opérations séparément. Fournir une telle fonction sans ce gain de performance peut être source de confusion.Si vous êtes juste à partager avec les puissances de deux, vous pouvez utiliser les opérateurs sur les bits:
(Le premier est le quotient, le deuxième le reste)
function divideByPowerOf2(num, exponent) { return [num >> exponent, num & ((1 << exponent) - 1)]; }
.Calcul du nombre de pages peut être fait en une seule étape:
Les mathématiques.ceil(x/y)
Vous pouvez utiliser ternaire de décider comment gérer positifs et négatifs des valeurs entières ainsi.
Si le nombre est positif, tout est très bien. Si le nombre est négatif, il faudra ajouter 1 à cause de la façon dont les Mathématiques.étage poignées négatifs.
Ce sera toujours tronquée vers zéro.
Vous ne savez pas si il est trop tard, mais ici, il va:
Si vous avez besoin de calculer le reste pour les très grands nombres entiers, ce qui la JS exécution ne peut pas représenter en tant que tel (un entier plus grand que 2^32 est représenté comme un flotteur et donc il perd en précision), vous devez faire certains truc.
Cela est particulièrement important de vérifier de nombreux cas, de vérifier les chiffres qui sont présents dans de nombreuses instances de notre vie quotidienne (numéros de compte en banque, cartes de crédit, ...)
Tout d'abord vous avez besoin de votre numéro de chaîne (sinon, vous avez déjà perdu la précision et le reste n'a pas de sens).
A présent, vous devez diviser votre chaîne dans les petites pièces, assez petit donc la concaténation de tout le reste et un morceau de ficelle peut s'adapter à 9 chiffres.
Préparer une expression régulière pour fractionner la chaîne
Par exemple, si
digits
est de 7, la regexp estElle correspond à une non vide de sous-chaîne de longueur maximale 7, qui est suivi (
(?=...)
est une anticipation positif) par un certain nombre de caractères qui est multiple de 7. Le " g " est de rendre l'expression de courir à travers toute la chaîne, de ne pas s'arrêter au premier match.Maintenant convertir chaque partie en entier, et de calculer les résidus par
reduce
(rajout du précédent reste - ou 0 - multiplié par la bonne puissance de 10):Cela fonctionne en raison de la "soustraction" le reste de l'algorithme:
qui permet de remplacer tout "première partie" de la représentation décimale d'un nombre avec son reste, sans affecter le reste final.
La version finale du code ressemblerait à: