Archived

This topic is now archived and is closed to further replies.

wamingo

no error on float division by zero? (vc6)

Recommended Posts

I fell over a bug in my code and thought that was strange because the program ran flawlessly as if there was no bug... I was diving an integer by a float which at a certain stage equalled zero. I never thought of it any further because it never made an error or warning or anything... If you divide an integer by 0 stored in a float it errors out... but if you divide by a float it does not? eg: int A=0; float B=0; A = int( 10 / B ); this compiles and runs flawlessly in vc++6.0 but is it okay or is it bad practice? And more specifcly how come it doesn''t error out? thanks.

Share this post


Link to post
Share on other sites
division by zero with integers makes your program crash, but if you do it with floating point numbers, the result will be some special floating point number called nan (not a number). I guess if you convert a nan to an int, it results in 0.

My Site

Share this post


Link to post
Share on other sites
yes it equals zero.
but is it okay practice to do this?
I''d love if it was fine because then I don''t have to make any if-div0 on my handling of screen size proportion which is where I found my "bug".
but on the other hand I don''t wanna get some bad programming habbit either...

Share this post


Link to post
Share on other sites
They say something about this in msdn. There is a way to have it so floats call up exceptions, the default is that they don't do anyhting when they have dividing or... forgot the other one... errors.

[edited by - Newfound Ajarn on January 15, 2004 6:52:03 PM]

Share this post


Link to post
Share on other sites
Ajarn, I looked really hard but couldn''t find anything :/ But thanks though.

RM, I don''t WANT to divide by zero as such it''s just that in the example above ''B'' "sometimes" equals 0; for instance if you wanted to divide by ANY pixel coordinate, well, pixels 0,0 is also a valid cordinate and so I ask whether I should be bothered with it or not... I just feel it''s good to know these things because then I stop worrying about it and do whatever is common practice.

Share this post


Link to post
Share on other sites
It doesn''t error out explicitly, but you can catch it. Try this:

float a = 0.f
float b = 6 / a;
if (b != b)
{
// NaN, float division by 0

}


It''s an interesting property. After performing the math on b, the result is NaN (not a number). A NaN, when tested for equality, is not even equal it itself, that''s why you can use the if conditional like that.

Share this post


Link to post
Share on other sites
If you run fallenang3l's code in .NET 2003, b = 1.#INF, or positive infinity, non NaN. This makes me wonder about three things. One, why was it changed from VC++6 to VC++7, since (at least to me) it makes more sense to have NaN returned for an undefined result rather than positive infinity? Two, why is a hardware exception not thrown, as is the case with integer division by 0? Third, if you search through MSDN, there's a section on C++ Multiplicative Operators which says "Division by 0 in either a division or a modulus expression is undefined and causes a run-time error." Not only is the result here not undefined (it's actually positive infinity), but it does not cause a run-time error. Apparently, Microsoft sometimes doesn't even conform to it's own documentation--kind of like b != b, eh?

[edited by - iamjoesname on January 18, 2004 1:45:04 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by iamjoesname
If you run fallenang3l''s code in .NET 2003, b = 1.#INF, or positive infinity, non NaN. This makes me wonder about three things. One, why was it changed from VC++6 to VC++7, since (at least to me) it makes more sense to have NaN returned for an undefined result rather than positive infinity? Two, why is a hardware exception not thrown, as is the case with integer division by 0? Third, if you search through MSDN, there''s a section on C++ Multiplicative Operators which says "Division by 0 in either a division or a modulus expression is undefined and causes a run-time error." Not only is the result here not undefined (it''s actually positive infinity), but it does not cause a run-time error. Apparently, Microsoft sometimes doesn''t even conform to it''s own documentation--kind of like b != b, eh?

[edited by - iamjoesname on January 18, 2004 1:45:04 AM]


It makes sense for it to return pos. infinity. Take a look at the graph of 1 / x as x->0+.

Share this post


Link to post
Share on other sites
quote:
Original post by fallenang3l
It makes sense for it to return pos. infinity. Take a look at the graph of 1 / x as x->0+.


Yes, the lim x->0+ 1/x is positive infinity. However, the statement "float a = 0.0f; float b = 6/a;" is not a limit. It''s simply a division by 0 statement. Returning positive infinity here is just mathematically incorrect; 6/0 does not equal positive infinity--it''s undefined. NaN seems the better option to me.

Share this post


Link to post
Share on other sites
quote:
Original post by iamjoesname
If you run fallenang3l''s code in .NET 2003, b = 1.#INF, or positive infinity, non NaN. This makes me wonder about three things. One, why was it changed from VC++6 to VC++7, since (at least to me) it makes more sense to have NaN returned for an undefined result rather than positive infinity? Two, why is a hardware exception not thrown, as is the case with integer division by 0? Third, if you search through MSDN, there''s a section on C++ Multiplicative Operators which says "Division by 0 in either a division or a modulus expression is undefined and causes a run-time error." Not only is the result here not undefined (it''s actually positive infinity), but it does not cause a run-time error. Apparently, Microsoft sometimes doesn''t even conform to it''s own documentation--kind of like b != b, eh?

[edited by - iamjoesname on January 18, 2004 1:45:04 AM]


1) NaN is the result of floating point operations that are mathematically undefined. 1.0/0.0 is infinite (represented as a number with maximum exponent - 127 for float, 1023 for double - and zero mantissa), ok, but 0.0/0.0 is Not a Number (NaN)

2) It depends on the architecture. There are signalling NaNs and non-signalling NaNs. When a signalling NaN is returned, a hardware exception is raised (if the hardware supports it) and it is converted to a non-signalling NaN.

3) I assume the page referred to integer operations: I believe the modulus operator is not defined for floating-point numbers. As for the reason for floats'' behaviour, that''s the way the IEEE 754 standard wants it. It also states that NaN != X for all values of X, including NaN.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan (C programming language co-inventor)

Share this post


Link to post
Share on other sites
quote:
Original post by iamjoesname
Yes, the lim x->0+ 1/x is positive infinity. However, the statement "float a = 0.0f; float b = 6/a;" is not a limit. It''s simply a division by 0 statement. Returning positive infinity here is just mathematically incorrect; 6/0 does not equal positive infinity--it''s undefined. NaN seems the better option to me.


Standard floating-point numbers are stored in a sign-exponent-mantissa form. It follows that there is both a ''positive zero'' [0 00000000 000000000000000] and a ''negative zero'' [1 00000000 000000000000000].

Floating point numbers may not behave entirely accurately in mathematical terms (after all, they only cover a finite number of value), but not only are they fully specified (IEEE 754 - Standard for Binary Floating-Point Arithmetic), returning an infinite value is more useful than getting a NaN regardless.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan (C programming language co-inventor)

Share this post


Link to post
Share on other sites
Yes. There are some algorithms where it''s useful to be able to distinguish the +0 result from -0, too.

Though if I were designing a number format I think I''d want to have separate values to indicate ''positive zero'', ''negative zero'' (both as limiting cases) and plain old 0 (which gives NaNs on division, because there''s no way to know which side the limit ought to be taken from).

Share this post


Link to post
Share on other sites