Divide by zero prevention

后端 未结 3 953
攒了一身酷
攒了一身酷 2020-12-11 16:58

What is 1.#INF and why does casting to a float or double prevent a division by 0 of crashing?
Also, any great ideas of how to pre

相关标签:
3条回答
  • 2020-12-11 17:16

    Wwhy using (float) or (double) prevents a division by 0 of crashing?

    It doesn't necessarily. The standard is amazing spare when it comes to floating point. Most systems use the IEEE floating point standard nowadays, and that says that the default action for division by zero is to return ±infinity rather than crash. You can make it crash by enabling the appropriate floating point exceptions.

    Note well: The only thing the floating point exception model and the C++ exception model have in common is the word "exception". On every machine I work on, a floating point exception does not throw a C++ exception.

    Also, any great ideas of how to prevent division by 0?

    1. Simple answer: Don't do it.
      This is one of those "Doctor, doctor it hurts when I do this!" kinds of situations. So don't do it!

    2. Make sure that the divisor is not zero.
      Do sanity checks on divisors that are user inputs. Always filter your user inputs for sanity. A user input value of zero when the number is supposed to be in the millions will cause all kinds of havoc besides overflow. Do sanity checks on intermediate values.

    3. Enable floating point exceptions.
      Making the default behavior to allow errors (and these are almost always errors) to go through unchecked was IMHO a big mistake on the part of the standards committee. Use the default and those infinities and not-a-numbers will eventually turn everything into an Inf or a NaN.
      The default should have been to stop floating point errors in their tracks, with an option to allow things like 1.0/0.0 and 0.0/0.0 to take place. That isn't the case, so you have to enable those traps. Do that and you can oftentimes find the cause of the problem in short order.

    4. Write custom divide, custom multiply, custom square root, custom sine, ... functions.
      This unfortunately is the route that many safety critical software systems must take. It is a royal pain. Option #1 is out because it's just wishful thinking. Option #3 is out because the system cannot be allowed to crash. Option #2 is still a good idea, but it doesn't always work because bad data always has a way of sneaking in. It's Murphy's law.

    BTW, the problem is a bit worse than just division by zero. 10200/10-200 will also overflow.

    0 讨论(0)
  • You usually check to make sure you aren't dividing by zero. The code below isn't particularly useful unless nQuota has a legitimate value but it does prevent crashes

    int nQuota = 0;
    int nZero = 0;
    float fZero = 0;
    if (nQuota)
        nZero = 3 / nQuota;
    cout << nZero << endl;
    
    if (nQuota)
        fZero = 2 / nQuota;
    cout << fZero << endl;
    
    0 讨论(0)
  • 2020-12-11 17:27

    1.#INF is positive infinity. You will get it when you divide a positive float by zero (if you divide the float zero itself by zero, then the result will be "not a number").

    On the other hand, if you divide an integer by zero, the program will crash.

    The reason float fZero = 2 / nQuota; crashes is because both operands of the / operator are integers, so the division is performed on integers. It doesn't matter that you then store the result in a float; C++ has no notion of target typing.

    Why positive infinity cast to an integer is the smallest integer, I have no idea.

    0 讨论(0)
提交回复
热议问题