C++ Division by 0

Division by zero: Undefined Behavior or Implementation Defined in C and/or C++?

I don't see any contradiction. Division by zero is undefined, period. There is no mention of "... unless INFINITY is defined" anywhere in the quoted text.

Note that nowhere in mathematics it is defined that 1 / 0 = infinity. One might interpret it that way, but it is a personal, "shortcut" style interpretation, rather than a sound fact.

Division result is always zero

because in this expression

t = (1/100) * d;

1 and 100 are integer values, integer division truncates, so this It's the same as this

t = (0) * d;

you need make that a float constant like this

t = (1.0/100.0) * d;

you may also want to do the same with this

k = n / 3.0;

Define division by zero as infinity

If you require this behaviour, use floating point numbers, which can represent infinity, and provide the desired behaviour. Note that technically this is undefined behaviour but in practice most compilers (all mainstream compilers for standard architectures) implement IEEE 754 semantics, e.g. GCC.

int main() {
float f = 42;
float g = f / 0.0f;
printf("%f\n", g);
}

Output:

inf

This is behaviour that can be relied on since it’s clearly documented by the compilers. However, when writing portable code make sure that you test these assumptions inside your code (e.g. by testing whether the preprocessor macro __STDC_IEC_559__, as well as compiler-specific macros are defined).

If, for some reason, you need this behaviour for integer values, the only recourse is to make your own type. Something like this:

typedef struct {
int value;
bool is_inf;
bool is_nan;
} ext_int;

ext_int make_ext_int(int i) {
return (ext_int) {i, false, false};
}

ext_int make_nan() {
return (ext_int) {0, false, true};
}

ext_int make_inf(int sign) {
return (ext_int) {(sign > 0) - (sign < 0), true, false};
}

ext_int ext_div(ext_int a, ext_int b) {
if (a.is_nan || b.is_nan) {
return make_nan();
}
if (b.value == 0) {
return make_inf(a.value);
}
// TODO: insert other cases.
return (ext_int) {a.value / b.value, false, false};
}

… in a real implementation you’d pack the different flags rather than having a separate bool for each, of course.

how to check if there is a division by zero in c

#include<stdio.h>
void function(int);

int main()
{
int x;

printf("Enter x:");
scanf("%d", &x);

function(x);

return 0;
}

void function(int x)
{
float fx;

if(x==0) // Simple!
printf("division by zero is not allowed");
else
fx=10/x;
printf("f(x) is: %.5f",fx);

}

The behaviour of floating point division by zero

Division by zero both integer and floating point are undefined behavior [expr.mul]p4:

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division
of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. ...

Although implementation can optionally support Annex F which has well defined semantics for floating point division by zero.

We can see from this clang bug report clang sanitizer regards IEC 60559 floating-point division by zero as undefined that even though the macro __STDC_IEC_559__ is defined, it is being defined by the system headers and at least for clang does not support Annex F and so for clang remains undefined behavior:

Annex F of the C standard (IEC 60559 / IEEE 754 support) defines the
floating-point division by zero, but clang (3.3 and 3.4 Debian snapshot)
regards it as undefined. This is incorrect:


Support for Annex F is optional, and we do not support it.

#if STDC_IEC_559


This macro is being defined by your system headers, not by us; this is
a bug in your system headers. (FWIW, GCC does not fully support Annex
F either, IIRC, so it's not even a Clang-specific bug.)

That bug report and two other bug reports UBSan: Floating point division by zero is not undefined and clang should support Annex F of ISO C (IEC 60559 / IEEE 754) indicate that gcc is conforming to Annex F with respect to floating point divide by zero.

Though I agree that it isn't up to the C library to define STDC_IEC_559 unconditionally, the problem is specific to clang. GCC does not fully support Annex F, but at least its intent is to support it by default and the division is well-defined with it if the rounding mode isn't changed. Nowadays not supporting IEEE 754 (at least the basic features like the handling of division by zero) is regarded as bad behavior.

This is further support by the gcc Semantics of Floating Point Math in GCC wiki which indicates that -fno-signaling-nans is the default which agrees with the gcc optimizations options documentation which says:

The default is -fno-signaling-nans.

Interesting to note that UBSan for clang defaults to including float-divide-by-zero under -fsanitize=undefined while gcc does not:

Detect floating-point division by zero. Unlike other similar options, -fsanitize=float-divide-by-zero is not enabled by -fsanitize=undefined, since floating-point division by zero can be a legitimate way of obtaining infinities and NaNs.

See it live for clang and live for gcc.



Related Topics



Leave a reply



Submit