WTF: 4 divided by 7 = 0, huh?!?

BlitzMax Forums/BlitzMax Programming/WTF: 4 divided by 7 = 0, huh?!?

pappavis(Posted 2006) [#1]
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?


Gabriel(Posted 2006) [#2]
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



pappavis(Posted 2006) [#3]

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.


Dreamora(Posted 2006) [#4]
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.


Gabriel(Posted 2006) [#5]
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.


CS_TBL(Posted 2006) [#6]
I tend to add .0 in these cases ..
4/7.0


Gabriel(Posted 2006) [#7]
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.


Dreamora(Posted 2006) [#8]
It actually has

1 is integer
1# or 1:float is float
1! or 1:double is double

:)


CS_TBL(Posted 2006) [#9]
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)


Gabriel(Posted 2006) [#10]
Yeah, I just don't find # and ! very readable. And :float doesn't seem any different from float()


pappavis(Posted 2006) [#11]

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));



H&K(Posted 2006) [#12]
@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.


Rambus(Posted 2006) [#13]
"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.


Dreamora(Posted 2006) [#14]
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.


Winni(Posted 2006) [#15]
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.


Grey Alien(Posted 2006) [#16]
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.)


pappavis(Posted 2006) [#17]
@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 ;).


Russell(Posted 2006) [#18]
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


marksibly(Posted 2006) [#19]
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!


tonyg(Posted 2006) [#20]
I would just be happy if "print 7/10.0" returned 0.7