How to determine the allowable value of a variable of type float , used as a divisor, to avoid division errors by zero? Is it enough to compare with zero?

 float f; //... if (f != 0.f) 1.f / f; 

Here is a similar question, where VladD refers to IEEE-754 , where it is guaranteed:

If v> 0 and h == 0, then v / h == INFINITY

If v <0 and h == 0, then v / h == -INFINITY

That, in principle, will allow to exclude checking for zero before dividing, but on the other hand, the standard 6.5.5.5 says:

The Result Of The First Operand; the result of the% operator is the remainder. In both operations, the behavior is undefined .

The question is whether it is safe to share a float with zeros, and if not, what should be the verification condition to get a certain result.

  • Well, logically, since the% operator participates in the second note, then this should apply only to integer types? .. - Harry
  • one
    @Harry well, obviously it is not spelled out, and following the same logic, clause 6.5.5.2 clearly says that integer is only for% - Vladimir Gamalyan
  • 6.5.5.5 explicitly for integers. I think you can safely share. The main thing is to accidentally bring the whole to a place. - gecube
  • @gecube I only have a draft of N1570, do you have explicitly spelled out integers in this paragraph? - Vladimir Gamalyan

2 answers 2

First of all I want to note that to find out the rules for working with floating point numbers in c or c++ you need to check the values ​​of the corresponding constants. Those. standards of languages ​​do not guarantee the existence of these rules, but there is a possibility to find out whether this or that implementation supports, for example, the IEEE-754 standard for a particular type.

Appendix F ( IEC 60559 floating-point arithmetic ) of the c standard clearly states:

An implementation that defines __STDC_IEC_559__ shall conform to this specification.

In c++ you can check IEEE-754 support for a real type with the following code:

 std::numeric_limits<T>::is_iec559 

True if and only type adheres to IEC 559 standard.
International Electrotechnical Commission Standard 559 is the same as IEEE 754.

If support is provided, then further investigation of the issue should be carried out according to the mentioned standard. But as practice shows, a division by zero error occurs exclusively when dividing by zero, although infinity can also be obtained when dividing by a nonzero value:

 #include <iostream> #include <cfenv> #include <limits> int main() { std::feclearexcept(FE_ALL_EXCEPT); float min = std::numeric_limits<float>::min(); volatile float zero = 0.0f; std::cout << 10.f / min << '\n'; if(std::fetestexcept(FE_DIVBYZERO)) { std::cout << "division by zero reported\n"; } else { std::cout << "division by zero not reported\n"; } } 

We get:

 inf division by zero not reported 

If we replace min by zero , then already :

 inf division by zero reported 

Therefore, you have to decide for yourself what you really want to avoid: the error of dividing by zero or getting infinity.

According to IEEE-754 p. 7.3, the "division by zero" exception occurs only when acting on the final operands in two cases:

  • division of a non-zero value by zero;
  • calculation of the logarithm of zero.
  • Those. assert(std::numeric_limits<float>::is_iec559) and no uncertainty? - Vladimir Gamalyan
  • And another such moment: "as practice shows, the division by zero error occurs exclusively when divided by zero", i.e. obviously this is not specified, even with is_iec559 ? - Vladimir Gamalyan
  • @VladimirGamalian, added a link to the ieee-754. - αλεχολυτ

I suspect that the Standard of the language should be based on IEEE-754 in matters of floating arithmetic, and everything else concerns only integers. The IEEE-754 Standard says that a non-zero value (including infinity) can be divided by zero, the result will be infinity. The division of zero by zero is also permissible, and we get quite NaN, that is, an analog of some kind of uncertainty.

Agree, it would be strange that if the processor operates strictly according to IEEE-754, but the language compiler does not.

Further, if one fears that the result may become infinite, the denominator does not have to be zero at all, it may be, for example, 0,5 , and the numerator is slightly more than half of the maximum possible value. It turns out that to avoid an infinite answer, it’s not enough to check the denominator at 0.0f , you need to obviously correlate the denominator with the numerator, and this can be done through division, before which, in fact, we are trying to make a check:) I doubt that the creators of the language are so short-sighted, that would have made such a blunder.

  • About the IEEE-754 standard is clear, and about the creators of the language, too, but still, where in the Chinese standard is this explicitly stated? So far I only see ..the behavior is undefined. . Although it is possible that all compilers in the world define such a situation unequivocally. - Vladimir Gamalyan
  • Well, the processor, in general, can only support integer operations. Well, Z80 for example) - Vladimir Gamalyan
  • 2
    I do not have the right to give you publicly the text of the Standard, since it is paid from Intel, but absolutely everything about the floating point can be found in the book Muller, Brisebarre. Handbook of Floating-Point Arithmetic Muller, Brisebarre. Handbook of Floating-Point Arithmetic , its pdf freely lying on the Internet. It is enough to read this book to consider yourself an expert on this topic. Actually, I did just that: I read this book and wrote almost the entire software implementation of all possible floating data types from 16 to 128-bit. A good book, everything is right there. - Zealint
  • one
    I apologize, I forgot another article with which you need to start, if you really are not at all familiar with the format: this one . - Zealint
  • one
    Also please pay attention to my new site and the corresponding section in it. Gradually, I will bring the site to a more convenient state, but you can read now. - Zealint