Rounding a number

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

Rounding a number

Postby Eddie » Feb 03, 2015 18:07

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
Site Admin
Posts: 6237
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Rounding a number

Postby counting_pine » Feb 03, 2015 20:56

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

Postby vdecampo » Feb 03, 2015 21:10

Just assign it to an Integer and it will round.

Code: Select all

Dim As Integer x = 3.5

x = 3.4
Print x
x = 3.5
Print x
sleep


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

Re: Rounding a number

Postby fxm » Feb 03, 2015 21:34

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

Postby Eddie » Feb 03, 2015 22:01

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: 6761
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Rounding a number

Postby dodicat » Feb 03, 2015 22:24

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

Postby MrSwiss » Mar 14, 2015 11:37

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

This code shows, that the rounding does exactly as advertised!
The comments are nothing for 'pros' but maybe helpful for beginners:

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#p204926
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

' ----- 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 position
Dim As ULong row_col = (45 Shl 16) + 120   ' 45=rows, 120=cols

Width 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 underline
row=6                              ' define loop start-row
For 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 loop
Next

row += 3 : Locate row, col               ' modify row (cursor positioning relative to current pos.)
Print "Any keypress exits program ...";

Sleep

Cls
End 0
' ----- end main ----- '
dafhi
Posts: 1367
Joined: Jun 04, 2005 9:51

Re: Rounding a number

Postby dafhi » Mar 15, 2015 5:10

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))
#endif

for 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

Postby BobPaw » Mar 17, 2015 15:13

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

Postby jona » May 23, 2015 0:41

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
Site Admin
Posts: 6237
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Rounding a number

Postby counting_pine » Aug 30, 2015 22:11

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.

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 6 guests