rounding to nearest number question?

BlitzMax Forums/BlitzMax Programming/rounding to nearest number question?

*(Posted 2010) [#1]
I always thought that int would round to the nearest number (like it used to do in all other basics I used) but in BlitzMax its basically the same as Floor so

Print Int( 40.5 )
Print Int( 40.6 )


both prints 40 which to me is strange. Anyone have any ideas as to why this is?


matibee(Posted 2010) [#2]
I think it's the way float to int conversions work. Use "int = (float + 0.5)" instead.


Jesse(Posted 2010) [#3]
blitzmax truncates. you can use what Matibee said or you can use "Ceil" or "Floor" depending on your needs.
[edit]
oops! I missed the part where you mention Floor. yes Matebee solution is most appropriate.


Czar Flavius(Posted 2010) [#4]
Floor rounds to the nearest lowest number, whereas Int deletes the decimal. Floor(-4.5) = -5 and Int(-4.5) = -4. This is standard behavior. Try matibee's suggestion.


*(Posted 2010) [#5]
Ok just I thought it might have been an oversight as loads of other basic dialects have a int function that rounds the number to the nearest whole number.


ziggy(Posted 2010) [#6]
Matibee's jugestions works great except for negative numbers.
use int = float + 0,5 * sgn(float) if you want to make it compatible with negative float values.
code:
Function round:Int(f:Float)
Return f + 0.5 * Sgn(f)
End Function



John G(Posted 2010) [#7]
I believe Ziggy is correct. INT(-0.9) = 0 and INT(+0.9) = 0 in BMax.


Jesse(Posted 2010) [#8]
I thought Matibee's made sense, since rounding up is actually increasing.


John G(Posted 2010) [#9]
If you just add half (+0.5) to all floats before converting to INT, then f = -1.4 converts to zero (0). There is still a Dead-space 1.999999 wide near zero.


Jesse(Posted 2010) [#10]
so neither one is accurate? (for the sake of rounding up)


ziggy(Posted 2010) [#11]
No, the code I posted is accurate because on negative numbers it substracts 0.5 so: -1.4 - 0.5 = -1.9 that rounds to -1, while if you round -1.6 and substract 0.5 it is: -1.6 -0.5 = -2.1 wich is truncated to -2. When te number is possitive, instead of substract, it adds, so it works ok too.

Give it a try yourself.
SuperStrict
Repeat
    Local a:Float = Float(Input("Number to round>"))
    Print "Rounded: " + round(a)
Forever
Function round:Int(f:Float)
    Return f + 0.5 * Sgn(f)
End Function 



Yan(Posted 2010) [#12]
http://blitzbasic.com/Community/posts.php?topic=62410#697453


*(Posted 2010) [#13]
Yan: I get 'Error:Internal error' with that link :s


Czar Flavius(Posted 2010) [#14]
It says
Function Round(value!)
  Return value! + (0.5 * Sgn(value!))
End Function



Jesse(Posted 2010) [#15]
my definition of rounding up means rounding to the next highest value not the absolute number value. and I believe it's called Symmetrical Arithmetic rounding
now I am more confused than ever. which one should I use?


Floyd(Posted 2010) [#16]
which one should I use?

Whichever one is appropriate for your needs. We don't know what those are.

The original question was about rounding to the nearest integer. Ideally that would be the method called "Banker's rounding" or "round to even". That's what Blitz3D uses. But the simpler method given by Ziggy is good enough for most uses.


Jesse(Posted 2010) [#17]
my fault. It was supposed to be rhetorical.


ziggy(Posted 2010) [#18]
wrong post. forget it!


Zeke(Posted 2010) [#19]
how about c-round function?

round.bmx:
SuperStrict

Import "round.c"

Extern "c"
	Function round_:Int(value:Float)
End Extern

Print round_(0.5)
Print round_(-0.5)
Print round_(1.4)
Print round_(-1.4)
Print round_(1.6)
Print round_(-1.6)


round.c:
//round.c

int round_(float value) {
	return round(value);
}



ziggy(Posted 2010) [#20]
@Zeke: Good point, maybe this is simpler:
Extern "c"
    Function Round:Double(value:Double) = "round"
End Extern
Print Round(0.6)
Print Round(0.4)
Print Round(1.6)
Print Round(2.6)
Print Round(3.6)

No need a single line of C code for rounding, and a s single BMX file.


Czar Flavius(Posted 2010) [#21]
I think it's interesting that round, ceil and floor return floats. I guess a car with a wheel missing is still not a trike.


Floyd(Posted 2010) [#22]
They return floating point values so they don't fail miserably with very large numbers.

You might want a floating point value which happens to be a whole number or you might want an integer value, i.e. the languages integer data type.

With RoundingFunction:Double( value:Double ) you can do both. Use the returned value directly as a double or assign it to an integer variable. If the function returned an integer then the first scenario would not work properly with doubles which are too large to fit into an integer.