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.
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.
Well, something divided by 0 is infinity is the only case when we use limit.
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.
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.
Can division by non-zero still create a nan / infinity
Yes.
If IEEE-754 is followed then:
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).
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With