WTF: 4 divided by 7 = 0, huh?!?
BlitzMax Forums/BlitzMax Programming/WTF: 4 divided by 7 = 0, huh?!?
| ||
I have encountered something very weird. Blitzmax cant do floating point maths?!? Blitz reports that (4/7) = 0.0000. WTF?!?! My verison of Blitz is 1.22. this is the code that generates the above output. Strict Local objApp:clsMain = New clsMain; objApp.main(); Type clsMain Method main() Print "START" Print Double(4/7) '// windows calculator reports 4/7=0,57142857142857142857142857142857 End Method End Type Then building the code. Building afronding toets wat werk nie Compiling:afronding toets wat werk nie.bmx flat assembler version 1.66 3 passes, 3952 bytes. Linking:afronding toets wat werk nie.debug.exe Executing:afronding toets wat werk nie.debug.exe Process complete running the code produces this output Building afronding toets wat werk nie Executing:afronding toets wat werk nie.debug.exe START 0.00000000000000000 Process complete Where is my trouble? Why dod i get such a ridcilous error? |
| ||
You're dividing two integers, giving you an integer result, and then casting the result to a double. No good casting when the division has already been done. Cast either ( or both ) sides of the equation before it occurs and you're fine.Strict Local objApp:clsMain = New clsMain; objApp.main(); Type clsMain Method main() Print "START" Print Double(4)/7 '// windows calculator reports 4/7=0,57142857142857142857142857142857 End Method End Type |
| ||
Cast either ( or both ) sides of the equation before it occurs and you're fine. Is that a quirk only to BlitzMax, coz i can nearly bet that C# in the dotnet framework doesnt behave this way. |
| ||
It is no quirk. All Blitz languages behave like this and I think even C behaves this way our would if / was defined on integer. Int / Int -> Int If you want -> float you have to either: float / int or int / float same for double. |
| ||
Is that a quirk only to BlitzMax, coz i can nearly bet that C# in the dotnet framework doesnt behave this way. I don't currently have C# installed so I can't say if that's true or not. What I can say is that there is something seriously wrong with C# if it gives you a double result from dividing two integers. EDIT: In fact, I'm almost certain C# won't do what you say it will, but perhaps I'm wrong. |
| ||
I tend to add .0 in these cases .. 4/7.0 |
| ||
I tend to add .0 in these cases .. I do as well, but I'm not sure if that automatically casts to a float or a double. Since he specifically wanted a double, and I thought adding .0 might be casting to a float, I played safe and suggested explicit casting. Would be nice if BMax had the old .0f or .0d that C has, but if you ( or someone else ) is certain whether .0 casts to float or double, that would suffice. |
| ||
It actually has 1 is integer 1# or 1:float is float 1! or 1:double is double :) |
| ||
I actually wonder why daddyfish wishes for a double. The only case where I ever used a double was when calculating oscillators (sound). With floats there was too much quantisation noise.. :P But other than that and other academic formulae, doubles -to me- appear to be a bit overrated. (ofcourse, someone's going to prove me otherwise ;P) |
| ||
Yeah, I just don't find # and ! very readable. And :float doesn't seem any different from float() |
| ||
I actually wonder why daddyfish ... ;). I wanted to doa position scaling in a little thingy i was working on. when I did this things were giving me th e wanted results. Thanx to all for the help print(Double(4) / Double(7)); |
| ||
@Gab, I agree, I think it lazy to use # and !, (And I can never remember which is which) Also maybe A:float/b is the same as Float (a)/b or not, but I can see that the second is a cast, however for const I would 7:float/b rather than Float (7)/b, not for any reason, just that I would type it out that way without thinking @ Pap Print 4/Double (7) or Print Double(4)/7 would do. |
| ||
"Is that a quirk only to BlitzMax, coz i can nearly bet that C# in the dotnet framework doesnt behave this way. " C++, C#,Java and C all behave the same way as blitzmax in this case. I would imagine almost any language would as well. H&K's fix above looks like it would work the way you want it to. |
| ||
float() is a function that converts to float ie a runtime conversion 3:float on the other side is a declaration so the number is compiled as float, no runtime conversion. The result is the same, but not so the speed. |
| ||
As for the C# debate. This code also returns 0 in Mono 1.2: using System; class Hello { static void Main() { System.Console.WriteLine(4/7); } } But this returns 0.5714285: using System; class Hello { static void Main() { float f = 4; System.Console.WriteLine(f/7); } } So there's nothing wrong with BlitzMax, I'd say. |
| ||
Yeah I always end up stuffing .0 on the end of a number. I also got confused a while ago with why float(10/3) doesn't work, so it's a good tip that you can go float(10)/3 for example (this is more useful when the const are variables that are Integer for example.) |
| ||
@Winni yes, you are correct, there's nothing wrong with BlitzMax. Just goes to show, Programming 101 is an essential course for any would-be coder ;). |
| ||
Still, the BMax manual says: If either argument is Double then result is Double else if either argument is Float then result is Float else if either argument is Long then result is Long else result is Int Since 4 and 7 are both Ints (why should BMax assume otherwise?) the result should, at the very least, be a Long, IMHO. But certainly not a Float or Double (without my specifically requesting/casting it so). Russell |
| ||
Hi, Max does indeed work a lot like c/c++/java/c# (and pretty much every language I've ever used), but I'd hesitate to say this means it's necessarily 'right'. In Max/C/C++ etc, types are determined 'bottom up' - ie: to determine the type of an expression, you first determine the type of it's sub-expressions, and so on recursively in a 'bottom up' manner. But another option would be calculate type 'top down' - ie: an expression is evaluated with a type passed down from a super-expression. You'd need a 'root' type to drive everything, but this would just be either the type of a variable if the expression was for an assignment, the type of a function parameter if the expression was for a function call, type 'Int' if the expression is for an array index and so on. This way, you could indeed "Print 5/10" and get ".5" back, which I think would be pretty cool. There are apparantly other benefits to this technique, including more precise math ops, but before anyone gets carried away this will not be appearing in Max as it would affect a lot of existing code! |
| ||
I would just be happy if "print 7/10.0" returned 0.7 |