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.
Rounding a number

 Site Admin
 Posts: 6237
 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.
EDIT: One small cautionary note: due to rounding precision on the +0.5, 0.49999999999999994 may round up instead of down.
Re: Rounding a number
Just assign it to an Integer and it will round.
Vince
Code: Select all
Dim As Integer x = 3.5
x = 3.4
Print x
x = 3.5
Print x
sleep
Vince
Re: Rounding a number
No, the to Integer rounding is like Cint(): "roundtoeven method".
counting_pine is right.
counting_pine is right.
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.
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.
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
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!
The comments are nothing for 'pros' but maybe helpful for beginners:
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 (02182015), 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 startrow
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  '
Re: Rounding a number
Int() is known for being slow
if speed is imortant, use this
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.00.5)shr 1)
#define ceil(x) ((((x)*2.00.5)shr 1))
#endif
for s as single = 0.5 to 2.5
? s; " >"; floor(s+0.5)
next
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?
[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?
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.

 Site Admin
 Posts: 6237
 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 floatingpoint 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 floatingpoint representation, which is (I think) 0.5*(12^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*(22^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 floatingpoint ops on it, e.g. divide and multiply by x.
If you read my note too quickly, it might have looked like a standard warning about floatingpoint 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 floatingpoint representation, which is (I think) 0.5*(12^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*(22^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 floatingpoint ops on it, e.g. divide and multiply by x.
Who is online
Users browsing this forum: No registered users and 6 guests