Problem with powers

BlitzMax Forums/BlitzMax Programming/Problem with powers

ChristianK(Posted 2006) [#1]
I have a little problem with powers.

x = 4
Print x^2

gives me a 15.999999999999998.
Have i done something wrong?


GfK(Posted 2006) [#2]
That's quite odd! Same result even if you declare X as an integer.

Print 4^2 gives the right result. I appreciate this is a fairly useless reply.

[edit]
x:int = 4
y:int = x^2
print y

15! Heh!


Gabriel(Posted 2006) [#3]
I'd assume that ^ is a floating point operator, and automatically casts to float when you use it. This is probably why it's slow and people recommend avoiding it.


Dreamora(Posted 2006) [#4]
^ has 2 implementations, float and double.
If you don't declare the variables correctly and explicitely, it will most likely end with float (which is faster than double) which gives incorrect result.

Using x^2:double should give the correct result.


TomToad(Posted 2006) [#5]
I only see one implementation of ^ and it is:
double bbFloatPow( double x,double y )
Which is in Blitz_cclib.c
You can prove it by putting:
printf("I am in bbFloatPow now!\n");
fflush(stdout);

into the function and recompiling. You will see that no matter how it is cast, the one version is always called.


H&K(Posted 2006) [#6]
It doesnt matter if dream is right about float and double, any whole number ^ 2 should give the right value
x:Float = 4.0 ^ 2.0
Print x
Prints 16
x:Float = 4.0
Y:Float = x^2.0
Print y
Prints 16
x:Float = 4.0
Print x^2.0
Prints 15.999999999998
This is a bug with Print


TomToad(Posted 2006) [#7]
No, it's not a bug with print. 4.0^2.0 returns a double. By doing x:float = 4.0 ^ 2.0, you are casting the double to a lower precision float, which happens to truncate the inacurate bits. When you Print x^2.0, it is printing the entire Double result. Try casting the result to float like this
x:Float = 4.0
Print Float(x^2.0)

It now prints 16.

The problem is with the ^ opperator itself. It doesn't distinguish the different types of variables passed to it, treating them all like doubles. Then after some checks for range and negatives, it passes the parameters into the Log() and Exp() functions which take Doubles as parameters. This will always create precision problems like with any floating point numbers.


H&K(Posted 2006) [#8]
Edited

Yep, your right. Thats bloody stupid.

I do not believe that pow 2 should ever be wrong on a power of 2
which happens to truncate the inacurate bits

Im not saying you are wrong, but that is stupid. There shouldnt be inacurate bits if all the numbers are whole numbers within 2^16 of each other

Well there is no question of not using RoR for int now is there


TomToad(Posted 2006) [#9]
You could change the brl.mod/blitz.mod/blitz_cclib.c to edit bbFloatPow() like this:
double bbFloatPow( double x,double y ){
	return pow(x,y);
}
Then rebuild. It'll be a tad slower, but it will be more accurate.


tonyg(Posted 2006) [#10]
I *HATE* floats...
x:Float = 1.0
For loopy:Float = 0.0 To 1.1 Step 0.1
	y:Float = x - loopy
	Print y
Next

Don't care about floating point precision, 1.0 - 0.1 = 0.9
and that's final.


H&K(Posted 2006) [#11]
@tonyg,

Thats a pain, but as I would expect that sort of behavior it wouldnt catch me out. This 4^2 tho is just stupid.


tonyg(Posted 2006) [#12]
It was mentioned here .
I just hate floats. It seems to give an excuse to return the wrong result.


Dreamora(Posted 2006) [#13]
Uuuh yeah sure, its an excuse that 0.1 can't be represented precise enough with large scale values if float is used ...

Why don't you just use int if you are unabled to program calculation stable stuff with float? (you know, there is a whole 4 year study including Master just to learn how to do this and similar stuff avoiding floating point precision problems or even double precision problems)


H&K(Posted 2006) [#14]
@Tonyg,

Tony that was my thread. (I did miss that ^2 didnt work right, other than when I would have expected it to not work right)

@Dream, yes, this time its a rubbish excuse. Surly you can see that in whole numbers, saying Sorry float cannot represent powers of 2 is a very bad excuse


tonyg(Posted 2006) [#15]

Uuuh yeah sure, its an excuse that 0.1 can't be represented precise enough with large scale values if float is used ...


It's just 'wrong'. Calculators can do it, B3D can do it.
I don't give a stuff about any technical explanation.
A simple sum should return the right answer.


Why don't you just use int if you are unabled to program calculation stable stuff with float?


Working around something is fine. Having to like it is a different matter.

(you know, there is a whole 4 year study including Master just to learn how to do this and similar stuff avoiding floating point precision problems or even double precision problems)


That's handy. Whoever coded B3D seemed to have done the course. Maybe they should give the Bmax developer a few pointers... errr... hold on!
Anyway, I'm just using the opportunity to slag off the implementation again.