Division

Blitz3D Forums/Blitz3D Programming/Division

big10p(Posted 2005) [#1]
Subject: Integer division in blitz3D.

11 / 2 = 5 ; Fine - just as expected.

-11 / 2 = -5 ; Fine - just as expected.

a = -11
a / 2 = -6 ; Uh?

Discuss.


Sledge(Posted 2005) [#2]
Look at it this way and you can see it's consistent:
a=-10
While Not KeyHit(1)
Print a+"/2     "+a/2
a=a+1
WaitKey
Wend


EDIT: Sorry, my original post's code was not actually very illustrative of the consistency - what's there now is better.

Anyway, to give an example: If you try 9/2 (which is 4.5) Blitz will return 4, which is rounded down. Well, if you round down -4.5 then you get -5. This accounts for the discrepancy you are seeing.


Floyd(Posted 2005) [#3]
This is actually a bug. The results with constants are evaluated by the compiler and are correct.

The problem with variables is that Blitz tries to optimize division by a power of 2, replacing it with a sign-preserving shift. This rounds the wrong direction for negative numbers.
m1 = -1

Write " -1 divided by 7, 8, 9  =  "
Print ( m1 / 7 ) +  ", " + ( m1 / 8 ) + ", " +  ( m1 / 9 )

WaitKey

No matter what you think about which way the rounding should go it is clear those three numbers should be the same. In fact they should all be zero.


Banshee(Posted 2005) [#4]
floor(), int(), ceil()


Koriolis(Posted 2005) [#5]
That's still a bug Becky Rose.
By using Floor, int or ceil you'll effectively work around the problem, but only because then blitz will work on floats, in which case it won't try to be clever and use shifting. Also you then have a more limited range of values where it can work (basically the range of the floating points matissa), and not the whole integer range.


big10p(Posted 2005) [#6]
Look at it this way and you can see it's consistent:

Yes, it is consistent - consistently wrong! :)

The problem with variables is that Blitz tries to optimize division by a power of 2, replacing it with a sign-preserving shift. This rounds the wrong direction for negative numbers.

That does explain it. TBH, I'm gob-smacked this bug exists ("-1 / 8 = -1" :O lol) - it could cause bugs that would be very hard to track down. Mark must have realized there'd be problems doing it this way with negative numbers. :/

No matter what you think about which way the rounding should go...

As far as I'm concerened, an integer division should simply throw away any remainder - whether it's +ve or -ve numbers involved. Blitz is supposed to appeal to novice programmers who have little understanding of what a compiler is doing under the hood. When encountering such a bug, they (and me) would just see the results as being plain wrong. We shouldn't have to take bugs like this on the chin and accept them, IMO. Silly.

[/end rant] :)


Sledge(Posted 2005) [#7]

Yes, it is consistent - consistently wrong! :)



The point being that, because it's consistent, you can account for it. You don't have to account for it using floats, either.


big10p(Posted 2005) [#8]
The point being that, because it's consistent, you can account for it.

I understand what you mean, my point was that we shouldn't have to. :)


Sledge(Posted 2005) [#9]

I understand what you mean, my point was that we shouldn't have to. :)



I know what you're saying. The opposite side of the argument would be to ask why folk should have to put up with slower, more scientifically accurate math in a game-oriented BASIC.

ie http://www.blitzbasic.com/Community/posts.php?topic=39883&hl=floating%20point%20error

It's also not like it isn't documented:
http://www.blitzbasic.com/faq/faq_entry.php?id=35

EDIT: Although, oddly, the docs in the first link and the second make slightly different claims. It would be nice to be able to switch to whichever method was required - grant you that.