Handling div by zero

Miscellaneous Forums/General Discussion/Handling div by zero

I've been pondering the best way to handle 'division by zero' with floats, as evidenced in this thread: http://www.blitzbasic.com/Community/posts.php?topic=73503

Im using Blitz3D, but as I guess this isn't a language specific issue, I thought I'd cast the net wider, here.

What code do you use to protect against div by zero?

Is just adding an epsilon to all divisors a really bad idea? (even if you're not concerned with mega-accuracy, and can guarantee there'll be no significant cumulative effect).

Looking at Mark's geom code, the smallest epsilon I should use is .000001, right?

Thanks.

you could just test the value before using it to make sure its not a zero.

You could also use multiplication instead.

I dont think bmax lets you divide by zero if you use floats.

You could also use multiplication instead.

How can you turn a division into a multiplication without still having to do a division at some point?

Eg:
A=10/B

The only way I know to turn that into a muliplication is

A=10*(1/B)

If B is zero, you've divided by zero either way.

I have just used IF (x<>0) y=10\x

Same as vorderman ... I don't like the idea of using an epsilon value.

Stevie

I don't like the idea of using an epsilon value.
Why's that, Stevie?

Anyway, seems like a simple x<>0 check is the best way to go, then. Thanks.

I get around it by not allowing the code to do a division by zero in the first place.


Is just adding an epsilon to all divisors a really bad idea?



What if the number was already the negative of your epsilon value?


I have just used IF (x<>0) y=10\x



Me too.


I get around it by not allowing the code to do a division by zero in the first place.



That is what the above example does...

It depends what you're doing. Give us an example of where your code could divide by zero.

Why's that, Stevie?


I guess it depends on what you're doing with the result but the best example I can come up with is ..

A constraint holding 2 particles a set restlength away from each other. Partial pseudo code but you get the idea ..

EPSILON# = .000001
c\RestLength = 10.0

c\Length = Distance( c\P1 , c\P2 ) + EPSILON
Diff# = .5 * ( c\Length - c\RestLength ) / c\Length 
Dx# = c\P1\x - c\P2\x
Dy# = c\P1\y - c\P2\y
c\P1\x = c\P1\x + Dx * Diff
c\P1\y = c\P1\y + Dy * Diff
c\P2\x = c\P2\x - Dx * Diff
c\P2\y = c\P2\y - Dy * Diff


If Distance( c\P1, c\P2 ) = 0 then Diff = ( .000001 - 10.0 / .000001 ) = -4999999.5

If you then move the two particles using this Diff factor then then the whole simulation explodes. Sure, most of the time all will be ok as long as the distance is > 0 but I like to avoid unforseen issues.

Stevie

If Distance( c\P1, c\P2 ) = 0
It never will be - not if P1 and P2 are floats.


It never will be - not if P1 and P2 are floats.



Why is it that you always think you know best!! I have come across plenty of more complex constraint based scenarios where the result is zero so I'll agree to disagree and leave it at that.

What happens if the result of your Distance() command just happens to return exactly the value of EPSILON?

Will you not then end up with c\length = 0 and it will then divide by zero and crash?

Local a:Float = 0
Print 100/a

It will not crash.

Stevie: I see your point but I'm not using anything as delicate as a physics sim. :)

What happens if the result of your Distance() command just happens to return exactly the value of EPSILON?

Will you not then end up with c\length = 0 and it will then divide by zero and crash?
This problem occured to me as well so forget I asked about just adding an epsilon to the divisor. ;)

Local a:Float = 0
Print 100/a

It will not crash.
I know, which is why I asked if checking for div by zero is even necessary, in the other thread I link to in the top post. :)

I wanted to get the definitive answer to this problem before I go back and retro-fit my entire library source with THE solution. :/

Local a:Float = 0
Print 100/a

It will not crash.


Yes, but it seems to return the value INFINITY - what happens if the variable which is then holding that undefined value is used further into your code - presumably it will all go badly wrong?

On my test that variable was then holding the value -2147483648, which can't be a good number to do anything with, let alone put through a timestep in a physics sim.

Far better to make sure the div by zero never occurs in the first place.


What happens if the result of your Distance() command just happens to return exactly the value of EPSILON?

Will you not then end up with c\length = 0 and it will then divide by zero and crash?



It would have to be -EPSILON for that to happen and that just isn't possible using pythagoras. All that would happen is that c\Length would be 2 x EPSILON. Away back to school the pair of you ;)

Stevie

Yes, I meant -EPSILON :)


It would have to be -EPSILON for that to happen and that just isn't possible using pythagoras. All that would happen is that c\Length would be 2 x EPSILON. Away back to school the pair of you ;)



LOL, distance equations aren't the only time somebody might divide by a float.

He was asking if all floats should get a epsilon added to them before dividing. Obviously that won't work if the number might be negative and possibly the negative of the epsilon.

He was asking if all floats should get a epsilon added to them before dividing. Obviously that won't work if the number might be negative and possibly the negative of the epsilon.
Yes, that's what I meant. Can I be excused from school now, please? :P


He was asking if all floats should get a epsilon added to them before dividing. Obviously that won't work if the number might be negative and possibly the negative of the epsilon.



I thought the question was specific to what I posted. Forgive me for not being a mind reader :)


Yes, that's what I meant. Can I be excused from school now, please? :P


Of course. There's some shadey guy with a box of puppies waiting on you!

Why is it that you always think you know best!!
Why is it you think I think I know best?

I have come across plenty of more complex constraint based scenarios where the result is zero
Name one. More specifically, name one were floating point generational inaccuracies will give you an exact division by zero (and a NaN or Inf value)?

I have had the problem using floating points when they are rounded to a certain value to allow grid-based placement, for example the grid coord is rounded to the nearest 0.1 or 0.01 etc..., making it quite easy to get a match between 2 values and thus a divide by zero.


Why is it you think I think I know best?


I've been on these forums for a very long time now, as have you. I suggest you have a read of some of your posts.


Name one. More specifically, name one were floating point generational inaccuracies will give you an exact division by zero (and a NaN or Inf value)?



For example, if you initially position 2 pointmasses in exactly the same place with the same mass and the constraint has a zero restlength. Sure, the distance between them may not be zero after 1 or 2 timesteps but it's initial length is.

At no point did I suggest that using floats resulted in divisions by zero or Nan's.

A good thread (despire the whingy bits).

From it we've established that its better to check for a division by zero not because it will crash or not, but because it will give us really bad numbers.

If divisor <> 0 do division... else do constant result

This seems the best way to handle it.