Division by zero
Blitz3D Forums/Blitz3D Programming/Division by zero
| ||
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. |
| ||
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. |
| ||
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 |
| ||
I always multiply instead of dividing... So if you want to make something half size use x * .5 rather than x / 2. That's a neat solution when you know the divisor, but what about a situation like this? :Using this method you will never get division by 0 and multiplying by 0 gives a result of 0 safely. 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. :) |
| ||
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. |
| ||
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 |
| ||
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! :) |
| ||
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. |
| ||
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. |
| ||
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). |
| ||
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. |