Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can division by non-zero still create a nan / infinity

I have a number which might be zeros. I divide by that number so I want to test if it's zero to prevent NaN's and infinitys. Is it possible that I still create NaNs / infinity because of rounding errors within the division?

double x; // might be zero
double y;

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

EDIT

Thanks for the responses. I'll add some subquestions then.

1) assuming neither x nor y is NaN / +inf or -inf, would a division that results in -inf / +inf result in more CPU cycles or any other unwanted behaviour? (Could it crash?)

2) is there a way to prevent the division from resulting in infinity? Using offsets and so on.

like image 845
ruhig brauner Avatar asked Jul 25 '16 15:07

ruhig brauner


People also ask

Is NaN division by zero?

Values like INFINITY and NaN are available for floating-point numbers but not for integers. As a result, dividing an integer by zero will result in an exception. However, for a float or double, Java allows the operation.

What division results in infinity?

Well, something divided by 0 is infinity is the only case when we use limit.

Is a number divided by 0 infinity?

It is well known that you cannot divide a number by zero. Math teachers write, for example, 24 ÷ 0 = undefined. They use analogies to convince students that it is impossible and meaningless, that “you cannot divide something by nothing.” Yet we also learn that we can multiply by zero, add zero, and subtract zero.

Why you can't divide by zero?

The short answer is that 0 has no multiplicative inverse, and any attempt to define a real number as the multiplicative inverse of 0 would result in the contradiction 0 = 1.


3 Answers

Can division by non-zero still create a nan / infinity

Yes.

If IEEE-754 is followed then:

  • If either operand is NaN, the result will be NaN.
  • If both numerator and denumerator are infinity, the result is NaN.
  • If only the numerator is infinity, the result is infinity.
  • If division by small denumerator (or large numerator) overflows, the result may be infinity, depending on current rounding mode.

Rules of other representations may be different.


2) is there a way to prevent the devision from resulting in infinity

This should go a long way in preventing that:

#include <cfenv>
#include <cassert>
#include <cmath>
#include <limits>

// ...

static_assert(std::numeric_limits<decltype(x)>::is_iec559, "Unknown floating point standard.");
#pragma STDC FENV_ACCESS ON
int failed = std::fesetround(FE_TOWARDZERO);
assert(!failed);
if(x != 0 && std::isfinite(x) && std::isfinite(y))
    return y / x;
else
    throw std::invalid_argument("informative message");

Some compilers may need non-default options to enable full IEEE 754 compliance (-frounding-math on GCC).

like image 52
eerorika Avatar answered Oct 19 '22 11:10

eerorika


Dividing a very small number into a very large number, or multiplication of two very large numbers, may yield an "infinity". Dividing an infinity by another infinity will yield a NaN. For example, (1E300/1E-300)/(1E300/1E-300) or (1E300*1E300)/(1E300*1E300) will both yield NaN.

like image 25
supercat Avatar answered Oct 19 '22 12:10

supercat


Yes, just look at code below

#include <iostream>
int main ()
{
    double x = 1, y = 2;
    while (y != 0) {
        std::cout << y << " " << x / y << std::endl;
        y /= 2;
    }
}

at some moment you will get:

8.9003e-308 1.12356e+307
4.45015e-308 2.24712e+307
2.22507e-308 4.49423e+307
1.11254e-308 8.98847e+307
5.56268e-309 inf
2.78134e-309 inf
1.39067e-309 inf
6.95336e-310 inf
like image 30
vadikrobot Avatar answered Oct 19 '22 12:10

vadikrobot