web-dev-qa-db-fra.com

Le meilleur moyen de prévenir/gérer la division par javascript

Quel est le meilleur moyen d'éviter la division par 0 en javascript qui accepte les entrées de l'utilisateur. S'il n'y a pas de moyen particulier d'y parvenir, quel serait le meilleur moyen de gérer une telle situation afin d'éviter d'autres scripts d'exécuter?

Toutes les idées sont très appréciées.

18
dibs

Il n’ya aucun moyen de le faire avec les opérateurs normaux / et /=.

La meilleure façon de faire ce que vous voulez est avec les gardes:

function notZero(n) {
  n = +n;  // Coerce to number.
  if (!n) {  // Matches +0, -0, NaN
    throw new Error('Invalid dividend ' + n);
  }
  return n;
}

et puis faire la division comme

numerator / notZero(denominator)

Sinon, vous pouvez toujours garder la sortie

function dividend(numerator, denominator) {
  var quotient = numerator / denominator;
  if (quotient !== quotient) { throw new Error(numerator + " / " + denominator); }
  return quotient;
}

mais cela perd la lisibilité et l'expressivité de /=.

17
Mike Samuel

De prime abord, vous pourriez:

  1. Vérifiez l'entrée de l'utilisateur pour voir si le dénominateur est zéro (ou évalué à zéro, en fonction de ce que votre script fait réellement).
  2. Vérifiez si le résultat de l'action isFinite() et si ce n'est pas le cas, gérez-le correctement.
5
maerics

quel serait le meilleur moyen de gérer une telle situation de manière à ne pas empêcher d'autres scripts de s'exécuter

La division par zéro ne semble pas empêcher l'exécution d'autres scripts en JavaScript:

var a = 20;
var b = 0;
var result = a/b;
console.log(result); // returns Infinity

Si vous voulez que quelque chose de différent se produise en cas de division par zéro, vous pouvez utiliser

function divideIfNotZero(numerator, denominator) {
  if (denominator === 0 || isNaN(denominator)) {
        return null;
  }
  else {
        return numerator / denominator;
  }
}
4
am2124429

Pour empêcher l'exécution (non désirée)

  1. Toujours vérifier critique entrée utilisateur et/ou résultats
  2. Utilisez une logique et/ou des rappels que vous pouvez empêcher d’exécuter
  3. Sur les formulaires HTML, etc., vous pouvez utiliser return false; comme valeur pour arrêter la soumission.
2
Smamatti

J'espère que c'est utile

(denominator != 0 ? nominator/denominator : Infinity)

ou quelle que soit la valeur que vous voulez mettre à la fin.

Salutations.

1
AlexMethod

Pourquoi ne pas simplement vérifier si le dénominateur est zéro?

if(x != 0) z = y / x;

Vous pouvez également vérifier si le résultat est Infinity:

3 / 0 == Infinity

Résultats en true;

(Testé uniquement en chrome.)

1
GAgnew

La meilleure façon est contextuelle. Mais voici le plus simple:

function myFunction( input ){
    input = 0 ? 0.0001 : input; // same as if( input == 0 ){ input = 0.0001; }
    return 1 / input;
}

Fondamentalement, si l'entrée est zéro, convertissez-la en un très petit nombre avant de l'utiliser comme dénominateur. Fonctionne très bien pour les entiers, car après votre division, vous pouvez les arrondir.

Quelques mises en garde empêchent que cela soit universel:

  • Cela pourrait provoquer de faux positifs si votre saisie accepte de très petits nombres
  • Il ne déclenchera aucun code de traitement d'erreur si vous devez faire quelque chose de spécial si vous entrez zéro.

C'est donc mieux pour les cas généraux et non critiques. Par exemple, si vous devez renvoyer le résultat d'un calcul complexe sans vous soucier de savoir si la réponse est exacte à N chiffres (déterminée par 0,0001 vs. 0.00000001, etc.); vous ne voulez tout simplement pas que cela se brise sur une division par zéro.

Comme autre réponse suggérée, vous pouvez également créer une fonction globale réutilisable.

function divisor( n ){ return ( n = 0 ? 0.0001 : n ); }
function myFunction( input ){ return 1 / divisor( input ); }

Améliorations possibles:

function divisor( n, orError ){
    if( typeof n == 'undefined' || isNaN( n ) || !n ){
        if( orError ){ throw new Error( 'Divide by zero.' ); }
        return 0.000000000000001;
    }else{ return 0 + n; }
}

Cela prendrait any valeur (null, nombre, chaîne, objet) et si non valide ou zéro, renverrait la valeur de type sécurité à zéro. Cela contraindrait également la sortie à un nombre juste au cas où il s'agirait d'une chaîne et que vous feriez quelque chose de bizarre. Tout cela assurerait que votre fonction de diviseur a toujours fonctionné. Enfin, dans les cas où vous souhaitez gérer vous-même de telles erreurs, vous pouvez définir le second paramètre sur true et utiliser un try/catch.

0
Beejor

Un peu différent de l'arrêt de l'exécution, mais l'opérateur ternaire est un moyen assez astucieux de personnaliser l'affectation de variables.

var one = 1,
    zero = 0,
    customValue = 1;


var quotient = zero===0 ? customValue : one / zero;

Ainsi, en définissant customVariable sur l'entier de votre choix, vous pouvez vous attendre à un résultat prévisible lorsque la division par zéro se produit.

0
ShaneSauce