Problem with powers
BlitzMax Forums/BlitzMax Programming/Problem with powers
| ||
I have a little problem with powers. x = 4 Print x^2 gives me a 15.999999999999998. Have i done something wrong? |
| ||
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! |
| ||
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. |
| ||
^ 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. |
| ||
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. |
| ||
It doesnt matter if dream is right about float and double, any whole number ^ 2 should give the right valuex:Float = 4.0 ^ 2.0 Print xPrints 16 x:Float = 4.0 Y:Float = x^2.0 Print yPrints 16 x:Float = 4.0 Print x^2.0Prints 15.999999999998 This is a bug with Print |
| ||
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 thisx: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. |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
@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. |
| ||
It was mentioned here . I just hate floats. It seems to give an excuse to return the wrong result. |
| ||
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) |
| ||
@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 |
| ||
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. |