Int(x:Float) for -ve doesn't work the same as BMax

Monkey Forums/Monkey Programming/Int(x:Float) for -ve doesn't work the same as BMax

Grey Alien(Posted 2013) [#1]
I have a rounding function in BlitzMax and Monkey that looks like this:

Function ccRound:int(value:Float)
Return int(value + 0.5)
End Function

The problem is I'm getting different results. For example:

		Print ccRound(9.1)
		Print ccRound(9.5)
		Print ccRound(9.9)
		Print ccRound(10)
		Print ccRound(-9.1)
		Print ccRound(-9.5)
		Print ccRound(-9.9)
		Print ccRound(-10)

Gives this in BlitzMax:
9
10
10
10
-9
-9
-10
-10

and this in Monkey:

9
10
10
10
-8
-9
-9
-9

As you can see, they are the same for positive numbers but not for negative numbers.

It looks like Blitzmax truncates floats DOWN to make ints and Monkey truncates DOWN for +ve ints and UP for -ve ints!

I noticed this because I called ccRound on -10.0 and expected to get an int of -10 but it returned -9!

I can fix this by having ccRound test for -ve numbers and subtracting 0.5 instead of adding it before returning the int but it will slow down that function a lot when called many times (I often call it on coordinates when I'm drawing stuff for example).

What do you make of this?

[EDIT]The fix I mentioned mostly works except of course any values that are negative and something.5 will round DOWN to the nearest int, not up as you might be expecting.


Jesse(Posted 2013) [#2]
int(9.1 + .5) = 9 correct
int(9.5 + .5) = 10 correct
int(9.9 + .5) = 10 correct
int(10 + .5) = 10 correct
int(-9.1 + .5) = -8 correct
int(-9.5 + .5) = -9 correct
int(-9.9 + .5) = -9 correct
int(-10.0 + .5) = -9 correct




Gives this in BlitzMax:
9
10
10
10
-9
-9
-10
-10




I don't know where you got those Bmax values but I Got this:


9
10
10
10
-8
-9
-9
-9


therevills(Posted 2013) [#3]
Using BlitzMax 1.48:
Function ccRound:Int(value:Float)
	Return Int(value + 0.5)
End Function

Print ccRound(9.1)
Print ccRound(9.5)
Print ccRound(9.9)
Print ccRound(10)
Print ccRound(-9.1)
Print ccRound(-9.5)
Print ccRound(-9.9)
Print ccRound(-10)


And the Results:
9
10
10
10
-8
-9
-9
-9


Same as Jesse's...


Grey Alien(Posted 2013) [#4]
How very strange will check again.

Anyway therevills have you ever modified ccRound to treat -ve numbers differently or are you happy with it rounding towards zero?


Beaker(Posted 2013) [#5]
How about this?:
Function ccRound:Int(value:Float)
	Return Int(value + (0.5*Sgn(value)))
End Function



Floyd(Posted 2013) [#6]
Just about every language except the pre-Max Blitz ones convert float to int by truncation, i.e. discard anything after the decimal point.

The Int(value + 0.5) trick works for positive values, while Int(value - 0.5) works for negative.

As noted, you can do both with Int(value + 0.5 * Sgn(value) ).


ziggy(Posted 2013) [#7]
I fixed the version in your framework long time ago to take into account the sign, maybe you're using the modified version?

See here: http://www.blitzmax.com/Community/posts.php?topic=82765#933661

ans also maybe here: http://www.blitzmax.com/Community/posts.php?topic=82765#968813


Grey Alien(Posted 2013) [#8]
@Beaker: Ha, do you know I've credited the original ccRound to you in my source? Anyway, Yeah I guess I'll do something like that although it could still be quicker to use an if statement to check for a +ve or -ve int than calling another function (Sgn).

OK I found the different. It seems in BlitzMaz I was doing:

Return floor(value + 0.5)

Floor rounds down, not towards zero, which explains the difference. Sorry for the red herring folks!

@Ziggy: Thanks for that. Looks like it could be useful in non-speedy situations.


Chroma(Posted 2013) [#9]
I'm still getting my head around the slight differences between BMax and Monkey too GA. But I guess being able to translate to so many platforms has it's drawbacks (BUT NOT MANY!) :)


ziggy(Posted 2013) [#10]
it could still be quicker to use an if statement to check for a +ve or -ve int than calling another function (Sgn)
Sgn is a pure function, so it should get inlined (in this scenario translated to an If at compile time) in any proper compiler. Don't know how do all available final compilers work, but I would not be worried about using this function anywhere and any other pure function, anywhere. they're usually as quick as not calling them and coping/pasting their implementation.


Grey Alien(Posted 2013) [#11]
OK thanks for the heads up Ziggy.