Division by zero

Blitz3D Forums/Blitz3D Programming/Division by zero

big10p(Posted 2007) [#1]
I have several places in my current code (when scaling etc.) where it's possible a division by zero could occur.

Now, Blitz3D throws a division by zero error when using a constant zero (a# = b# / 0.0), but when using a variable as the divisor, B3D seems to handle the situation by returning a value of 'Infinity', and not ending the program with an error.

Is this situation guaranteed when dividing using a variable, or could my program still fail at some point with a division by zero error?

Also, the resultant 'Infinity' value is approximately equivalent to zero, right? I mean, if I scale an entity with it, it becomes invisible.

Anyone set my mind at rest on this as I'd prefer to not have to check for division by zero in-code. :)

Thanks.


Rob Farley(Posted 2007) [#2]
I always multiply instead of dividing... So if you want to make something half size use x * .5 rather than x / 2.

Using this method you will never get division by 0 and multiplying by 0 gives a result of 0 safely.


Stevie G(Posted 2007) [#3]
What you're getting is Nan = Not a number. In my opinion it's best to avoid all divisions by 0. While you may not get a MAV strange & unexpected things can start happening.

Stevie


big10p(Posted 2007) [#4]
I always multiply instead of dividing... So if you want to make something half size use x * .5 rather than x / 2.

Using this method you will never get division by 0 and multiplying by 0 gives a result of 0 safely.
That's a neat solution when you know the divisor, but what about a situation like this? :
ratio# = mesh_height# / mesh_width#

What you're getting is Nan = Not a number. In my opinion it's best to avoid all divisions by 0. While you may not get a MAV strange & unexpected things can start happening.
Hmm, is Infinity the same as NaN? When I print the value it says 'Infinity' not NaN. I know using NaN can cause weird things but I haven't noticed anything odd during testing. It almost seems as Infinity is treated as an extremely small fraction, which is basically what I want. :)


Terry B.(Posted 2007) [#5]
Just Ran some tests on this.
It works, as long as the varible is a float.
The code I used to test:

Local zero# =0
For a#=0 To 1000
b=a#/zero#
Print b
Next 
WaitKey()
End 


It gave me:
-2147483648
Over and over.
No error though.

EDIT: Changed b to a float, gave me infinity.
Intresting. Still no error though.


Sir Gak(Posted 2007) [#6]
Why not explicitly test for a zero condition, or perhaps a less than a very small finite amount?



If zero# < 0.000000001 then zero# = 0.000000001


big10p(Posted 2007) [#7]
Yeah, I guess I could test for zero but it *seems* as though I don't need to. That's what I'm asking about. :)

Faffing around testing for zero division all over the shop would be a pain, TBH. It would make the code less easy to read and execution speed is priority one, also.

I think I might just ignore the 'problem' - it's not for anything commercial, anyway. However, it would be nice to get a definitive answer from BRL about this. I can dream! :)


Floyd(Posted 2007) [#8]
Infinity is just what it sounds like, a number bigger than any ordinary number.

The value of 1/x gets bigger as x decreases toward zero. The limiting case is x=0, when 1/x has become infinitely large.

Notice that Infinity is an actual floating point value. But there are few cases where you can do anything useful with it. Continued calculation with infinite values usually leads to NaN, which is not a valid number and causes all sorts of trouble.

Whether this will be a problem in your program depends on what you are doing with the resulting infinite numbers. But unless you have a very good reason for believing it won't cause any trouble you should test for division by zero.


big10p(Posted 2007) [#9]
OK, thanks Floyd.

Is it possible to check the result for infinity?

Is the best way to check for div by zero 'If Abs(a#) < 0.000001 Then a# = Sgn(a#)*0.000001'? Not even sure the Sgn is needed?! Hmmm.

Thanks all.


Zethrax(Posted 2007) [#10]
If you're checking the result for infinity then you've gone one step too far. As stated above, use a conditional test to check if the divisor is a zero value before you perform the division. If it is a zero value, then abort the division and handle the situation in a manner appropriate to whatever you're trying to achieve (pop an error message, substitute an epsilon value, etc).


big10p(Posted 2007) [#11]
OK, so, the consensus seems to be I really should check for div by zero.

I may just use an epsilon on all divisions. This should be ok as long as the inaccuracy doesn't become cumulative. Hmmm.

Also, I forget - what's the smallest epsilon I can use in B3D? .000001 or .0000001?

Thanks.