how can i round numbers to a half?
eg.
4,48 => 4,5
4,02 => 4,0
4,95 => 5,0
Printable View
how can i round numbers to a half?
eg.
4,48 => 4,5
4,02 => 4,0
4,95 => 5,0
you could check to see if the first decimal place is above five then if it is round up and if it's not round to fve, multiple ifs to figure out where it goes.
Try this function:
Private Function Round(nValue As Double, nDigits As Integer) As Double
Round = Int(nValue * (10 ^ nDigits) + 0.5) / (10 ^ nDigits)
End Function
To round 4.48 to 4.5, you would say:
MsgBox Round(4.48, 1)
The 1 signifies the number of digits after the decimal point to carry out the rounding.
This works:
Use a function like this:
VB Code:
MyNum = Round(2 * MyNum, 0) / 2
As in:
VB Code:
Private Sub Command1_Click() Dim MyNum As Single '4,48 => 4,5 '4,02 => 4,0 '4,95 => 5,0 MyNum = 4.48 MyNum = Round(2 * MyNum, 0) / 2 MsgBox MyNum '''returns 4.5 from 4.48 MyNum = 4.02 MyNum = Round(2 * MyNum, 0) / 2 MsgBox MyNum '''returns 4 from 4.02 MyNum = 4.95 MyNum = Round(2 * MyNum, 0) / 2 MsgBox MyNum '''returns 5 from 4.95 End Sub
-Lou
NotLKH,
What about if the number is 0.25 this should be rounded to 0.5, yet your function results in zero?
You can try this:
VB Code:
Function NuRoundNearest(ByVal Number As Double, ByVal Interval As Double) As Double 'Nucleus 'Rounding Function developed to minimises floating point rounding errors If Interval = 0 Then NuRoundNearest = Number: Exit Function 'exit if interval = 0 Dim r As Double, i As Long Interval = Abs(Interval) 'only positive intervals considered r = Abs(Number) / Interval 'result from dividing number by interval i = Int(r) 'the Integer value from the initial division (e.g. If r = 1.3, i = 1) 'if remainder is less than 50% of the Next interval need to round down If r - i < 0.5 Then NuRoundNearest = i * Interval Else NuRoundNearest = (i + 1) * Interval If Number < 0 Then NuRoundNearest = NuRoundNearest * -1 ' account for negative numbers End Function
Example usage:
debug.print NuRoundNearest(4.48,0.5)
debug.print NuRoundNearest(4.02,0.5)
debug.print NuRoundNearest(4.95,0.5)
Heh, CODE WAR!!!Quote:
Originally posted by Nucleus
NotLKH,
What about if the number is 0.25 this should be rounded to 0.5, yet your function results in zero?
Any ways, then I Submit this single line Function:
:D :D :DVB Code:
Private Function ROUND_IT(ByVal MY_NUM As Single) As Single ROUND_IT = Round(2 * ((100 * MY_NUM + CDec((CBool(100 * MY_NUM Mod 5))) + 1) / 100), 0) / 2 End Function Private Sub Command4_Click() '4.48 => 4.5 '4.02 => 4.0 '4.95 => 5.0 '.25 => .5 '.26 => .5 '.24 => 0 MsgBox ROUND_IT(4.48) MsgBox ROUND_IT(4.02) MsgBox ROUND_IT(4.95) MsgBox ROUND_IT(0.25) MsgBox ROUND_IT(0.26) MsgBox ROUND_IT(0.24) End Sub
-Lou
BTW:
There is an anomaly with the way the roundfunction works
LKH's first try works as good as the ROUND-function can work.
in case you have a number like 0.5, 1.5, .2.5 etc it rounds to the next EVEN number. round(1.5) = 2 round(2.5) = 2.
great ain't it?
Helger
:confused: :confused: :confused:
MY CODE?
Which One?
-Lou
Making it a lot more complicated than it needs to be:
num = round(num*2,0)/2
enjoy!
this one:
MyNum = Round(2 * MyNum, 0) / 2
nothing wrong with it at all!
It's the Round function in itself that doesn't work as it should.
this is what you will get
x = round(1.5,0)
--> x = 2
x = round(2.5,0)
--> x = 2
and that is also why the
MyNum = Round(2 * MyNum, 0) / 2
approach won't work as ppl expect it to work - simply because Round wasn't implemented correctly by microsoft.
Helger
DaveAMS,
Been There, Done That:
Then Nucleus:Quote:
Originally posted by NotLKH
This works:
Use a function like this:
VB Code:
MyNum = Round(2 * MyNum, 0) / 2
-Lou
Please read more than the last post, next time.:DQuote:
Originally posted by Nucleus
What about if the number is 0.25 this should be rounded to 0.5, yet your function results in zero?
Anyways, My Last Function works as suggested for Pos values,
And for neg, rounds toward the greater .5, ie... -1.25 -> -1.
So,,, if you want -.25 -> -.5, AND .25 -> .5, My new function does it.
FYI,
Nucleus's code did this already {GOOD CODE!}
I just like Single Line Function Challanges.
VB Code:
Private Function ROUND_IT_2(ByVal MY_NUM As Single) As Single ROUND_IT_2 = ((-2) * CDec(CBool(MY_NUM + Abs(MY_NUM))) - 1) * Round(2 * ((100 * Abs(MY_NUM) + CDec((CBool(100 * (Abs(MY_NUM) Mod 5)))) + 1) / 100), 0) / 2 End Function Private Sub Command4_Click() 'For both Pos & Neg Orientations '4.48 => 4.5 '4.02 => 4.0 '4.95 => 5.0 '4.5 => 4.5 '3.5 => 3.5 '.25 => .5 '.26 => .5 '.24 => 0 MsgBox ROUND_IT_2(4.48) MsgBox ROUND_IT_2(4.02) MsgBox ROUND_IT_2(4.95) MsgBox ROUND_IT_2(4.5) MsgBox ROUND_IT_2(3.5) MsgBox ROUND_IT_2(0.25) MsgBox ROUND_IT_2(0.26) MsgBox ROUND_IT_2(0.24) MsgBox ROUND_IT_2(-4.48) MsgBox ROUND_IT_2(-4.02) MsgBox ROUND_IT_2(-4.95) MsgBox ROUND_IT_2(-4.5) MsgBox ROUND_IT_2(-3.5) MsgBox ROUND_IT_2(-0.25) MsgBox ROUND_IT_2(-0.26) MsgBox ROUND_IT_2(-0.24) End Sub
:D
-Lou
So...
Helger, any objections to My last Function?
-Lou
how about
num = cdbl(cint(num*2+.5))/2
heh,
You need to complicate it some more.
:D :D :D
Your function rounds .01 to .5, instead of to 0.
{MsgBox CLng(CInt((0.01) * 2 + 0.5)) / 2}
:D :D :D
-Lou
NotLKH: No objections to any of your functions :)
I only wanted to call to everybodies attention that microsoft messed up THEIR round-function.
Helger
hmmm...cint rounds up! I always thought it truncated.
num = Int(i * 2 + 0.5) / 2
this should work.
Very Good!
The only thing I found was -.25 goes to 0, So can you get
it to go to -.5 instead?
-Lou
speaking purely mathematically, -1.25 should round to -1, because you always round up (in the positive direction).
That being said, how about:
num = sgn(num) * Int(abs(num) * 2 + 0.5) / 2
Didn't test it, since it looks Perfect!!!
Good Job!
BTW, Thanks for pointing out the Sgn Function, I never knew about it. {Always thought there should be one, but never bothered to look for it.}
As far as I'm concerned, You've won the Golden Code Award for this Thread!!!
;) :D ;)
-Lou
Ahhh, 'tis a wonderful thing indeed to receive the praise of one's peers. It's just too bad I couldn't use any c++ pointers...
Well if we grow that rounding idea, to get a generalised rounding function that works for any interval we get a function that looks like this. You can use fix() instead of int() for symmetric arithmetic rounding.
VB Code:
Function RoundTo(Number As Double, Interval As Double) As Double Dim i# i = 1 / Interval RoundTo = Fix((Abs(Number) + Interval / 2) * i) / i If Number < 0 Then RoundTo = RoundTo * -1 End Function
Works in theory not in practice due to multiple rounding errors caused by computer rounding of floating point numbers where a decimal value e.g. 0.8 unable to be represented by binary system. In practice go for option that minimises such errors.
one way to avoid the rounding errors intrinsic in the IEEE floating-point representation, you could use the vb Currency data type. This actually stores an integer offset by 10,000: the number 12.3456 would be stored as 123456.
It's an 8-byte integer, so it can store number covering +/-900 trillion and change, to four-decimal precison.
*This data type also works well in situations where a long int would overflow (long int only covers +/-2 billion and change).
Yes that is one solution, however, it limits you to 4dp.
I've only seen two cases where anyone regularly rounds a number at intervals finer than two or three decimals:
3.1415926535897...
2.71828182846...
My personal favorite is people who leave fifteen decimals of precision on a solution to an equation, when the equation is based on data accurate to one or two decimal places. "If it has more numbers after the decimal place, it must be better!!!"