## Rounding a number

New to FreeBASIC? Post your questions here.
Eddie
Posts: 6
Joined: Feb 03, 2015 17:55

### Rounding a number

Is there a function that rounds a number like this?:

3.4 -> 3.0
3.8 -> 4.0
3.5 -> 4.0
4.5 -> 5.0

I know CINT() exists, but that's not what I need.

Thanks.
counting_pine
Posts: 6236
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

### Re: Rounding a number

It's not clear what you're looking for, but perhaps Int(x + 0.5) would serve your purposes. It always rounds .5 up, and will allow values outside the range of an Integer.

EDIT: One small cautionary note: due to rounding precision on the +0.5, 0.49999999999999994 may round up instead of down.
vdecampo
Posts: 2982
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

### Re: Rounding a number

Just assign it to an Integer and it will round.

Code: Select all

`Dim As Integer x = 3.5x = 3.4Print xx = 3.5Print xsleep`

-Vince
fxm
Posts: 10037
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: Rounding a number

No, the to Integer rounding is like Cint(): "round-to-even method".
counting_pine is right.
Eddie
Posts: 6
Joined: Feb 03, 2015 17:55

### Re: Rounding a number

counting_pine wrote:It's not clear what you're looking for, but perhaps Int(x + 0.5) would serve your purposes. It always rounds .5 up, and will allow values outside the range of an Integer.

Of course! I feel dumb now :)

Thank you.
dodicat
Posts: 6759
Joined: Jan 10, 2006 20:30
Location: Scotland

### Re: Rounding a number

The built in crt.bi makes use of C functions in FreeBasic.

The sprintf function from crt.bi is a type of formatting, which rounds numbers.

But to use sprintf, I made up a small function to directly input a number, and the required precision (decimal places).

It is a bit more general , it returns a string.

Code: Select all

` #include "crt.bi" function CRound(byval x as double,byval precision as integer=30) as string    if precision>30 then precision=30    dim as zstring * 40 z:var s="%." &str(abs(precision)) &"f"    sprintf(z,s,x)    return rtrim(rtrim(z,"0"),".")end function print 3.4,cround(3.4,0)print 3.8,cround(3.8,0)print 3.5,cround(3.5,0)print 4.5,cround(4.5,0)sleep `
MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: Rounding a number

@ dodicat,
great function, thank you, which IMO deserves a bit 'extended' demo code.

This code shows, that the rounding does exactly as advertised!

Code: Select all

`#include "crt.bi"' Function 'CRound(as Double,as Integer)as String' by dodicat' http://www.freebasic.net/forum/viewtopic.php?f=2&t=23274&p=204926#p204926function CRound(byval x as double,byval precision as integer=30) as string    if precision>30 then precision=30    dim as zstring * 40 z : var s="%." + str(abs(precision)) + "f"    sprintf(z,s,x)    return rtrim(rtrim(z,"0"), ".")end function' ----- main ----- '' tested: FreeBASIC Compiler - Version 1.02.0 (02-18-2015), built for win64 (64bit)Dim As Short row=2, col=2               ' title string start positionDim As ULong row_col = (45 Shl 16) + 120   ' 45=rows, 120=colsWidth row_col                        ' set console size, in rows(height) x columns(width)Cls                                 ' clear screen (console)Locate row, col    : Print "SPrintF.EXE -- Ver. 1.0.0 by MrSwiss / Function CRound() by dodicat";Locate row+1, col: Print String(67, "~");   ' print title underlinerow=6                              ' define loop start-rowFor i As Single = 1.499 To 1.501 Step 0.0001' Single prec. is sufficient here   Locate row, col   : Print CRound(i, 3)   ' Function call   Locate row, 9   : Print "rounded to 3rd decimal place"   Locate row, 41   : Print Str(i)         ' conversion (number to string)   Locate row, 49   : Print "number has 4th decimal place"   row += 1                         ' increase row by 1 within loopNextrow += 3 : Locate row, col               ' modify row (cursor positioning relative to current pos.)Print "Any keypress exits program ...";SleepClsEnd 0' ----- end main ----- '`
dafhi
Posts: 1367
Joined: Jun 04, 2005 9:51

### Re: Rounding a number

Int() is known for being slow

if speed is imortant, use this

Code: Select all

`#Ifndef floor ' http://www.freebasic.net/forum/viewtopic.php?p=118633  #Define floor(x) (((x)*2.0-0.5)shr 1)  #define ceil(x) (-((-(x)*2.0-0.5)shr 1))#endiffor s as single = 0.5 to 2.5  ? s; " ->"; floor(s+0.5)next`
BobPaw
Posts: 41
Joined: Dec 13, 2014 2:03
Location: Texas, USA

### Re: Rounding a number

You only need to use CInt() e.g.
[code file="RoundingDemo.bas]
Dim a As Double = 3.4
Dim b As Double = 3.5
''Double' is more precise than Single
Print a & " -> " & Cint(a)
Print b & "-> " & Cint(b)
Sleep
''Int' returns the floor of the number i.e. closer to zero
Print 3.4 & " -> " & Int(3.4)
Print -3.5 & " -> " & Int(-3.5)
[/code]
The real question is why not use CInt?
jona
Posts: 35
Joined: Aug 28, 2014 6:44
Location: Puerto Princesa, Palawan, Philippines

### Re: Rounding a number

counting_pine wrote:EDIT: One small cautionary note: due to rounding precision on the +0.5, 0.49999999999999994 may round up instead of down.

Won't 0.5 be recorded as an exact value because it's 2^(-1) or 0.1 in binary? I know that 0.1 in decimal presents a problem, because it has no exact binary representation. 0.1 decimal is 0.00011 etc (0/2 + 0/4 + 0/8 +1/16 + 1/32 + . . .) in binary.
counting_pine
Posts: 6236
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

### Re: Rounding a number

Sorry, I missed this post.
If you read my note too quickly, it might have looked like a standard warning about floating-point and decimals - you might have thought I was saying that 0.5 is actually stored as 0.499999... Which - you're absolutely correct - isn't true. 0.5 is stored exactly as 0.5.

The problem I'm talking about occurs (or may occur) with the number that's just below 0.5 in floating-point representation, which is (I think) 0.5*(1-2^-52).
If you increase its value by any amount, e.g. by adding 0.5 to it, you will need an extra bit to store the 2^-1 value, and you will lose the final bit of precision (2^-53). The exact result of the sum will be 0.999999... (0.5*(2-2^-52)), but with the final bit of precision lost, it may round up to 1.0.

But 0.499999... should round down to 0. It's a minor thing, but worth noting.
This number could probably occur in the wild if you take 0.5 and do some lossy floating-point ops on it, e.g. divide and multiply by x.