123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|197|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> Blitz -> Number bug in Blitz?

Mon, 30 Mar 2009, 11:03
Phoenix
Fiddling about with numbers in Blitz, I came across something odd.



This prints 'T'. It obviously shouldn't. I immediately tried this in both C and C#, and both yielded the expected result, 'F'. What could be causing this? Blitz handles numbers up to 2^31, so this should work. Thoughts?
Mon, 30 Mar 2009, 12:37
Afr0
Yes.
Your math is incorrect.

2^26 - 2 should be 2^24, not 2^26.

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Mon, 30 Mar 2009, 13:52
Phoenix
No, my math isn't incorrect. Firstly, due to operator precedence 2^26-2 is equal to (2^26)-2, not 2^(26-2). Secondly, the result of the program would be wrong even if we ignored operator precedence, because 2^24 isn't equal to 2^26 either.
Mon, 30 Mar 2009, 14:56
Jayenkai
QBasic used to really tick me off with this kinda thing.. (That was roughly when I started to do crazy-ass math* stuff!)
To be safe, I've stuck to using brackets for pretty much all my maths* ever since.

* Jay gets bonus points for using both "Math" AND "Maths" to please everyone.

-=-=-
''Load, Next List!''
Mon, 30 Mar 2009, 17:27
steve_ancell
Yes Phoenix, I can safely say that does not seem right. Looks like a bug to me !
Mon, 30 Mar 2009, 17:30
steve_ancell
It also tells porkies if you do it like this.


Mon, 30 Mar 2009, 19:07
JL235
I believe this is a problem with your code where the = binds tighter then the ^. Why? Cos it does in Java too and I need to use brackets to just get it to compile. i.e. your condition is approximately: (2^(26-2 == 2)^26)

Just try it with brackets!
Mon, 30 Mar 2009, 23:30
steve_ancell
Joe, I thought about that bracket thing also, but it didn't make any difference.

Is this what you meant ?


Mon, 30 Mar 2009, 23:35
steve_ancell
It doesn't work like this either.


Mon, 30 Mar 2009, 23:38
steve_ancell
It works if you replace the 26 with 25 though.
Mon, 30 Mar 2009, 23:58
JL235
The first one is the one I meant. My example is what _might_ be happening by the Blitz grammar when it parses it, not what your code should be. However you might want to bracket every operator, so I presume it's meant to be:
You could also try evaluating the left and right sides outside of the if statement and printing their values. Do this in C and C# too so you can see if the values are the same.

Dumb question, but you do know that ^ in Blitz is not the same as ^ in C right? In Blitz it's for power (why?), in all other languages it's the bitwise exclusive or. So in other languages you'd need to use something else.
Tue, 31 Mar 2009, 06:28
steve_ancell
JL235 Dumb question, but you do know that ^ in Blitz is not the same as ^ in C right? In Blitz it's for power (why?), in all other languages it's the bitwise exclusive or. So in other languages you'd need to use something else.


I never knew that, but seeing that I'm attempting to learn Java, I will keep that in mind. Cheers Joe
Tue, 31 Mar 2009, 06:36
Jayenkai
DD In Blitz it's for power (why?)


^ = Power because ^ = Power!!


-=-=-
''Load, Next List!''
Tue, 31 Mar 2009, 06:48
steve_ancell
That's a very Powerful statement Jay

*Pun intended.*
Tue, 31 Mar 2009, 09:05
Phoenix
Dumb question, but you do know that ^ in Blitz is not the same as ^ in C right? In Blitz it's for power (why?), in all other languages it's the bitwise exclusive or. So in other languages you'd need to use something else.


Yes, I am aware of this and used the provided functions from the other languages' standard libraries. Adding more brackets doesn't seem to resolve the problem either. I'd say that this is a bug.
Tue, 31 Mar 2009, 10:53
JL235
First I'd get BB to print out the sides independantly of the condition. This is just to find where the 'bug' is occuring.

In theory your code should be the same as:

Somehow I think that will give the correct answer (but please check).
Tue, 31 Mar 2009, 11:44
Phoenix


Result:
67108864
67108900.0

So I suspect that this is another case of floating point inaccuracy. The power operator returns a float.
Tue, 31 Mar 2009, 19:04
JL235
ahhhhh, because it returns a float the -2 is too small to have an impact. There they are both the same.

This is not a bug, but instead a limitation in float-point accuracy and in BB for not supplying doubles. If you change it to say:

I expect it will work correctly.
Tue, 31 Mar 2009, 20:14
Scherererer
I think it's a bug that blitz would be converting a power operator between two integers to a floating point value. My guess is that mark just had it input into the standard C library pow function and called it a day, thus we get floats instead of ints.

-=-=-
YouTube Twitter
Computer Science Series: Logic (pt1) (part 2) (part 3) 2's Complement Mathematics: Basic Differential Calculus
Wed, 01 Apr 2009, 01:31
JL235
Instinct I think it's a bug that blitz would be converting a power operator between two integers to a floating point value
What about 2^33? That's between two ints but can only be held (approximately) in a float rather then an int.

I think the best solution is to return longs or doubles since they are typically more then big enough for these things. If they aren't then you probably already know that they aren't and so can use something else.
Wed, 01 Apr 2009, 21:52
Evil Roy Ferguso
|edit| I can't remember my point here. I guess that means my point was that I should probably sleep sometimes hur hur hur. |edit|
Wed, 01 Apr 2009, 22:10
JL235
Maybe it's a sloppy implementation, but just to clarify this is not a bug and is normal behaviour as according to the IEEE floating point standard.

It's because the minimum values you can add/subtract to a float is relative to the value that the float is holding. If a float is holding a very big number then the smallest value you can add/subtract is also very big. In this case it is bigger then 2.

If you google I believe you can also find a java puzzler which describes the same problem in Java. It's something like: "make 'x-2 == x' evaluate to true". The solution is to make x equal to a very large floating point number.

Presumably the C# and C alternatives that Phoenix mentions in his first post returned doubles, not floats. Perhaps you should try casting the result to a float and see if it yields the same result as in BB.
Thu, 02 Apr 2009, 00:10
Phoenix




Nope, both work as expected with floats.
Thu, 02 Apr 2009, 12:34
Evil Roy Ferguso
Huh, this is kind of interesting. pow() is working as expected in the program above because it's written C, and C's pow() uses double-precision floats. powf() is used for single-precision floats, and exhibits the problem that we have seen in Blitz. C++'s pow() overloads based on the type of its parameters and I imagine that it would exhibit the behavior we're seeing too, unless a cast to double were involved.

This seems to fit in with Blitz's aversion to double-precision floats, but what really surprised me was that the expression 2^26 is treated as a floating-point value to begin with -- I would have expected Blitz to convert the result of the exponentiation to an integer when it knew that both the base and the mantissa were integers, so that the subsequent subtraction would be (int - int) instead of (float - float(int)). I guess this behavior is unintuitive more than wrong. Looks like Int(2^26)-2 is your friend.