Лучший способ предотвратить / обработать деление на 0 в JavaScript - PullRequest
20 голосов
/ 10 ноября 2011

Каков наилучший способ предотвратить деление на 0 в javascript, который принимает вводимые пользователем данные. Если нет конкретного способа достичь этого, что было бы лучшим способом справиться с такой ситуацией, чтобы не препятствовать выполнению других сценариев?

Любые идеи очень ценятся.

Ответы [ 8 ]

18 голосов
/ 10 ноября 2011

Нет способа сделать это с обычными операторами / и /=.

Лучший способ сделать то, что вы хотите, с охраной:

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

и затем делите как

numerator / notZero(denominator)

В качестве альтернативы вы всегда можете защитить выход

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

но это теряет читабельность и выразительность /=.

5 голосов
/ 10 ноября 2011

От верха моей головы вы могли бы:

  1. Проверить введенные пользователем данные, чтобы убедиться, что знаменатель равен нулю (или оценивается как ноль, в зависимости от того, что на самом деле делает ваш скрипт).
  2. Проверьте, если результат действия isFinite(), а если нет, то обработайте соответствующим образом.
4 голосов
/ 05 ноября 2015

Каков наилучший способ справиться с такой ситуацией, чтобы не препятствовать выполнению других сценариев

Деление на ноль не препятствует выполнению других сценариев в JavaScript:

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

Если вы хотите, чтобы в случае деления на ноль произошло что-то другое, вы можете использовать

function divideIfNotZero(numerator, denominator) {
  if (denominator === 0 || isNaN(denominator)) {
        return null;
  }
  else {
        return numerator / denominator;
  }
}
2 голосов
/ 10 ноября 2011

Для предотвращения (нежелательного) выполнения

  1. Всегда проверять критический пользовательский ввод и / или результаты
  2. Использовать логику и / или обратные вызовы, которые вы можете запретить выполнять
  3. В формах HTML и т. Д. Вы можете использовать, например, return false; в качестве значения, чтобы остановить отправку.
1 голос
/ 29 июня 2018

Надеюсь, это полезно

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

или любое другое значение, которое вы хотите поставить в конце.

Привет.

1 голос
/ 10 ноября 2011

Почему бы просто не проверить, равен ли знаменатель нулю?

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

Вы также можете проверить, равен ли результат бесконечности:

3 / 0 == Infinity

Результаты в true;

(проверено только в хром.)

0 голосов
/ 13 сентября 2018

Лучший способ - контекстный. Но вот самое простое:

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

В основном, если ввод равен нулю, превратите его в очень маленькое число, прежде чем использовать в качестве знаменателя. Прекрасно работает с целыми числами, так как после деления вы можете округлить их обратно вниз.

Пара предостережений мешают этому быть универсальными:

  • Это может привести к ложным срабатываниям, если ваш ввод принимает действительно маленькие числа
  • Это не вызовет никакого кода обработки ошибок, если вам нужно сделать что-то особенное, если введен ноль

Так что лучше всего подходит для некритических случаев общего назначения. Например, если вам нужно вернуть результат сложного вычисления, и вам все равно, точен ли ответ до N цифр (определяется как 0,0001 против 0,00000001 и т. Д.); Вы просто не хотите, чтобы оно делилось на деление на ноль.

Как показал другой ответ, вы также можете создать глобальную функцию многократного использования.

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

Возможные улучшения:

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; }
}

Это будет принимать любое значение (ноль, число, строка, объект) и, если оно недопустимо или равно нулю, возвращает отказоустойчивое нулевое значение. Это также приведет к выводу числа на случай, если это будет строка и вы делаете что-то странное. Все это гарантирует, что ваша функция делителя всегда работает. Наконец, для случаев, когда вы хотите обрабатывать такие ошибки самостоятельно, вы можете установить для второго параметра значение true и использовать try/catch.

0 голосов
/ 29 августа 2017

Немного отличается от остановки выполнения, но троичный оператор - довольно приятный способ настроить присвоение переменной.

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


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

Таким образом, установив customVariable в целое число по вашему выбору, вы можете ожидатьпредсказуемый результат при делении на ноль.

...