Division entière avec le reste en JavaScript?
en JavaScript, Comment puis-je obtenir:
- le nombre total de fois qu'un entier donné va dans un autre?
- le reste?
15 réponses
pour un certain nombre y
et un certain diviseur x
calculer le quotient ( quotient
) et le reste ( remainder
) comme:
var quotient = Math.floor(y/x);
var remainder = y % x;
Je ne suis pas un expert en opérateurs bitwise, Mais voici une autre façon d'obtenir le numéro entier:
var num = ~~(a / b);
cela fonctionnera correctement pour les nombres négatifs aussi bien, tandis que Math.floor()
tournera dans la mauvaise direction.
Cela semble correct ainsi:
var num = (a / b) >> 0;
j'ai fait des tests de vitesse sur Firefox.
-100/3 // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34, 0.5016 millisec
~~(-100/3) // -33, 0.3619 millisec
(-100/3>>0) // -33, 0.3632 millisec
(-100/3|0) // -33, 0.3856 millisec
(-100-(-100%3))/3 // -33, 0.3591 millisec
/* a=-100, b=3 */
a/b // -33.33..., 0.4863 millisec
Math.floor(a/b) // -34, 0.6019 millisec
~~(a/b) // -33, 0.5148 millisec
(a/b>>0) // -33, 0.5048 millisec
(a/b|0) // -33, 0.5078 millisec
(a-(a%b))/b // -33, 0.6649 millisec
ci-dessus est basé sur les 10 millions d'essais pour chaque.
Conclusion: utiliser (a/b>>0)
(ou (~~(a/b))
ou (a/b|0)
) pour obtenir un gain d'efficacité d'environ 20%. Aussi garder à l'esprit qu'ils sont tous incompatibles avec Math.floor
, quand a/b<0 && a%b!=0
.
ES6 introduit la nouvelle méthode Math.trunc
. Cela permet de corriger la réponse de @MarkElliot pour le faire fonctionner pour les nombres négatifs aussi:
var div = Math.trunc(y/x);
var rem = y % x;
notez que les méthodes Math
ont l'avantage sur les opérateurs bitwise qu'ils travaillent avec des nombres supérieurs à 2 31 .
Vous pouvez utiliser la fonction parseInt
pour obtenir un résultat tronqué.
parseInt(a/b)
pour obtenir un reste, utilisez l'opérateur mod:
a%b
parseInt ont quelques pièges avec des chaînes, pour éviter d'utiliser le paramètre radix avec la base 10
parseInt("09", 10)
dans certains cas, la représentation string du nombre peut être une notation scientifique, dans ce cas, parseInt produira un résultat erroné.
parseInt(100000000000000000000000000000000, 10) // 1e+32
Cet appel va produire 1 comme résultat.
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 plus petit que le paramètre", donc:
- nombres positifs: plancher (X)=partie entière de X;
- nombres négatifs: plancher (X)=partie entière de X moins 1 (parce qu'elle doit être plus petite que le paramètre, i.e., plus négatif!)
le reste est défini comme le "surplus" d'une division (arithmétique euclidienne). Quand le dividende n'est pas un entier, le quotient n'est généralement pas non plus un entier, i.e., il n'y a pas de reste, mais si le quotient est forcé d'être un entier (et c'est ce qui se produit quand quelqu'un essaie d'obtenir le reste ou le module d'un nombre à virgule flottante), il y aura un non-entier "sur", évidemment.
JavaScript 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é! La première question de Yarin N'était pas "quelle est la division entière de X par Y", mais "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, parce que la division entière (dividende par diviseur) sera -1 plus petit que le temps un nombre (diviseur) "va dans" un autre (dividende). En d'autres termes, le plancher retournera la réponse correcte pour une division entière d'un nombre négatif, mais Yarin n'a pas demandé cela!
gammax répondu correctement, que le code fonctionne comme demandé par Yarin. D'un autre côté, Samuel a tort, il n'a pas fait les maths, je suppose, ou il aurait vu que cela fonctionne (aussi, il n'a pas dit Quel était le diviseur de son exemple, mais j'espère que c'était 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 aussi avec des valeurs non-entières, à la fois pour le dividende et le diviseur. Exemple:
-100.34 / 3.57: GoesInto = -28, Reste = -0.380000000000000079
Oui, j'ai remarqué, il y a un problème de précision là, mais je n'ai pas eu le temps de le vérifier (Je Je ne sais pas si C'est un problème avec Firefox, Windows 7 ou avec mon CPU FPU). Pour la question de Yarin, cependant, qui implique seulement des entiers, le code de gammax fonctionne parfaitement.
Math.floor(operation)
renvoie la valeur arrondie vers le bas de l'opération.
exemple de 1 st question:
var x = 5;
var y = 10.4;
var z = Math.floor(x + y);
console.log(z);
de la Console:
15
exemple de 2 nd question:
var x = 14;
var y = 5;
var z = Math.floor(x%y);
console.log(x);
de la Console:
4
Alex Moore-Niemi commentaire comme réponse:
pour Rubyists ici de Google à la recherche de divmod
, vous pouvez l'appliquer comme tel:
function divmod(x, y) {
var div = Math.trunc(x/y);
var rem = x % y;
return [div, rem];
}
résultat:
// [2, 33]
si vous divisez avec des puissances de deux, vous pouvez utiliser des opérateurs bitwise:
export function divideBy2(num) {
return [num >> 1, num & 1];
}
export function divideBy4(num) {
return [num >> 2, num & 3];
}
export function divideBy8(num) {
return [num >> 3, num & 7];
}
(le premier est le quotient, le second le reste)
Calcul du nombre de pages peut être fait en une seule étape: Mathématique.ceil (x/y)
vous pouvez utiliser ternary pour décider comment gérer les valeurs entières positives et négatives ainsi.
var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1
si le nombre est positif, tout va bien. Si le nombre est négatif, il va ajouter 1 en raison de la façon dont les mathématiques.étage poignées négatifs.
j'utilise normalement (a - a % b) / b
. C'est probablement pas le plus élégant, mais il fonctionne.
ce sera toujours tronqué vers zéro. Je ne sais pas s'il est trop tard, mais voilà:
function intdiv(dividend, divisor) {
divisor = divisor - divisor % 1;
if (divisor == 0) throw new Error("division by zero");
dividend = dividend - dividend % 1;
var rem = dividend % divisor;
return {
remainder: rem,
quotient: (dividend - rem) / divisor
};
}
si vous avez besoin de calculer le reste pour de très grands entiers, que L'exécution JS ne peut pas représenter comme tel (tout entier supérieur à 2^32 est représenté comme un flotteur et donc il perd de la précision), vous devez faire un truc.
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 de chaîne (sinon, vous avez déjà perdu la précision et le reste n'a pas de sens).
str = '123456789123456789123456789'
vous avez maintenant besoin de diviser votre corde en plus petites parties, assez petit pour la concaténation de n'importe quel reste et un morceau de corde peut tenir dans 9 chiffres.
digits = 9 - String(divisor).length
préparer une expression régulière pour séparer la chaîne de caractères
splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')
par exemple, si digits
est 7, le regexp est
/.{1,7}(?=(.{7})+$)/g
correspond à une sous-couche non vide de longueur maximale 7, suivie ( (?=...)
est un lookhead positif) par un nombre de caractères qui est multiple de 7. Le ' g ' est de faire courir l'expression à travers toute la chaîne, sans s'arrêter au premier match.
convertissez maintenant 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):
reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor
Cela fonctionnera en raison de la" soustraction "reste algorithme:
n mod d = (n - kd) mod d
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.
le code final ressemblerait à:
function remainder(num, div) {
const digits = 9 - String(div).length;
const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g');
const mult = Math.pow(10, digits);
const reducer = (rem, piece) => (rem * mult + piece) % div;
return str.match(splitter).map(Number).reduce(reducer, 0);
}