39

What is the best way to prevent divide by 0 in javascript that is accepting user inputs. If there is no particular way to achieve this what would be the best way to handle such a situation so as to not prevent other scripts from executing?

Any insights are much appreciated.

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
dibs
  • 1,018
  • 2
  • 23
  • 35
  • Simply validate your input so entering 0 is impossible might be an option, validation is always a good thing :) – ChrisR Nov 09 '11 at 22:00
  • 2
    The "best way" would depend on the computations you're performing and the requirements you have. For instance, is it acceptable for a computation to always succeed but return an incorrect result when fed with invalid input? – Frédéric Hamidi Nov 09 '11 at 22:02

11 Answers11

34

There is no way to do that with the normal / and /= operators.

The best way to do what you want is with guards:

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

and then do division like

numerator / notZero(denominator)

Alternatively you can always guard the output

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

but that loses the readability and expressiveness of /=.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • 7
    Unless you need very performant code, I would use `if (n === 0 || isNaN(n)) {...}`. As it is, I would have forgotten that the NaN case is handled. I know coercion is part of the language, but it's still a bad idea for the most part IMO. Also `dividend !== dividend`? How about `isNaN(dividend)`? – Thomas Eding Nov 09 '11 at 23:30
  • @trinithis, I agree, `isNaN(dividend)` is more idiomatic and more readable. Numeric code is tricky to translate, so I tend to eschew casts and functions in favor of builtin operators that tend to be more portable than ancillary functions, but that may not matter for you. – Mike Samuel Nov 10 '11 at 00:33
  • Why `dividend`? – xehpuk Jun 29 '18 at 16:59
  • @xehpuk I'm not sure I understand your question. – Mike Samuel Jul 01 '18 at 13:31
  • 1
    Why this name for the function and the variable? Shouldn't it be quotient? – xehpuk Jul 01 '18 at 13:39
  • @zehpuk, you're right. I misused terminology. Feel free to edit. – Mike Samuel Jul 01 '18 at 13:55
  • I like that you "coerced" it. – PolymorphismPrince Nov 04 '18 at 21:00
9

Off the top of my head you could:

  1. Check the user input to see if the denominator is zero (or evaluates to zero, depending on what your script actually does).
  2. Check if the result of the action isFinite() and if not then handle appropriately.
maerics
  • 151,642
  • 46
  • 269
  • 291
8

what would be the best way to handle such a situation so as to not prevent other scripts from executing

Division by zero doesn't seem to prevent other scripts from execution in JavaScript:

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

If you want something different to happen in case of division by zero, you could use

function divideIfNotZero(numerator, denominator) {
  if (denominator === 0 || isNaN(denominator)) {
        return null;
  }
  else {
        return numerator / denominator;
  }
}
am2124429
  • 425
  • 2
  • 6
  • 8
  • I think implementing a utility method such as this is the best solution for this problem. I created `MyApp.Util` namespace and threw this in there. I use it all over the place. – Mattkwish Jun 15 '18 at 14:14
5

Hope this is useful

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

or whatever value you want to put at the end.

Greetings.

Alejandro Alvarez
  • 131
  • 1
  • 3
  • 9
  • 1
    this would return zero when dividing by negative values and that is an incorrect result – derloopkat Jun 29 '18 at 15:39
  • 1
    It's infinity, That's why I put or whatever you want to put at the end. I was trying to help, there's no need to be so rude! But thanks for your feedback – Alejandro Alvarez Jul 10 '18 at 21:42
2

To prevent (unwanted) execution

  1. Always verify critical user input and/or results
  2. Use logic and/or callbacks you can prevent to execute
  3. On HTML forms etc. you can use i.e. return false; as value to stop submission.
Smamatti
  • 3,901
  • 3
  • 32
  • 43
1

Why not just check if the denominator is zero?

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

You can also check if the result is Infinity:

3 / 0 == Infinity

Results in true;

(Only tested in chrome.)

GAgnew
  • 3,847
  • 3
  • 26
  • 28
  • 3
    `3 / 0 == Infinity` should be true in all browsers since there is only one sequence of bits that corresponds to a positive 64b IEEE-754 floating point value, but `-3 / 0 != Infinity` so the builtin `isFinite` helps here. If function call overhead is too costly, one quick way to filter out both infinite values and `NaN` is `x - x === 0` since that result is `0` for all finite numbers, and NaN for special floating point numbers. – Mike Samuel Nov 20 '11 at 17:59
0

A bit different than stopping execution, but the ternary operator is a pretty slick way to customize variable assignment.

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


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

This way, by setting the customVariable to the integer of your choice, you can expect a predictable result when division by zero occurs.

ShaneSauce
  • 209
  • 2
  • 9
0

The best way is contextual. But here's the easiest:

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

Basically if the input is zero, turn it into a very small number before using as a denominator. Works great for integers, since after your division you can round them back down.

A couple caveats prevent this from being universal:

  • It could cause false positives if your input accepts really small numbers
  • It won't trigger any error-handling code, if you need to do something special if zero is entered

So it's best for general-purpose, non-critical cases. For example, if you need to return the result of a complex calculation and don't care if the answer is accurate to N digits (determined by 0.0001 vs. 0.00000001, etc.); you just don't want it to break on a divide-by-zero.

As another answer suggested, you could also create a reusable global function.

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

Possible improvements:

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

This would take any value (null, number, string, object) and if invalid or zero, return the failsafe zero-like value. It would also coerce the output to a number just in case it was a string and you were doing something odd. All this would ensure that your divisor function always worked. Finally, for cases where you wanted to handle such errors yourself, you could set the second parameter to true and use a try/catch.

Beejor
  • 8,606
  • 1
  • 41
  • 31
0

Set a cap on what the value for the numerator can be and set the numerator to that value when the denominator equals 0.

LJD
  • 498
  • 4
  • 11
0
const progress = goal == 0 ? 0 : total/goal
Allan
  • 308
  • 2
  • 7
-1

This is a faster approach yet is confusing

let divisor;
let dividend;

let result =(dividend/divisor) || 0 

if the result for instance if you are calculating percentage is infinite you can give it 0 as value;

Arinzehills
  • 1,491
  • 10
  • 14