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
| ||
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. |
| ||
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 |
| ||
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... |
| ||
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? |
| ||
How about this?:Function ccRound:Int(value:Float) Return Int(value + (0.5*Sgn(value))) End Function |
| ||
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) ). |
| ||
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 |
| ||
@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. |
| ||
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!) :) |
| ||
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. |
| ||
OK thanks for the heads up Ziggy. |