Results 1 to 24 of 24

Thread: rounding numbers to .5

  1. #1

    Thread Starter
    Addicted Member c@lle's Avatar
    Join Date
    Oct 1999
    Location
    Belgium
    Posts
    179

    rounding numbers to .5

    how can i round numbers to a half?

    eg.

    4,48 => 4,5
    4,02 => 4,0
    4,95 => 5,0

  2. #2
    Frenzied Member numtel's Avatar
    Join Date
    Apr 2000
    Location
    CA
    Posts
    1,163
    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.

  3. #3
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333
    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.

  4. #4
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    This works:

    Use a function like this:

    VB Code:
    1. MyNum = Round(2 * MyNum, 0) / 2

    As in:

    VB Code:
    1. Private Sub Command1_Click()
    2. Dim MyNum As Single
    3. '4,48 => 4,5
    4. '4,02 => 4,0
    5. '4,95 => 5,0
    6. MyNum = 4.48
    7.     MyNum = Round(2 * MyNum, 0) / 2
    8.         MsgBox MyNum '''returns 4.5 from 4.48
    9. MyNum = 4.02
    10.     MyNum = Round(2 * MyNum, 0) / 2
    11.         MsgBox MyNum '''returns 4 from 4.02
    12. MyNum = 4.95
    13.     MyNum = Round(2 * MyNum, 0) / 2
    14.         MsgBox MyNum '''returns 5 from 4.95
    15. End Sub

    -Lou

  5. #5
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    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:
    1. Function NuRoundNearest(ByVal Number As Double, ByVal Interval As Double) As Double
    2.  'Nucleus
    3.  'Rounding Function developed to minimises floating point rounding errors
    4.  If Interval = 0 Then NuRoundNearest = Number: Exit Function 'exit if interval = 0
    5.  Dim r As Double, i As Long
    6.  Interval = Abs(Interval) 'only positive intervals considered
    7.  r = Abs(Number) / Interval 'result from dividing number by interval
    8.  i = Int(r)  'the Integer value from the initial division (e.g. If r = 1.3, i = 1)
    9.  'if remainder is less than 50% of the Next interval need to round down
    10.  If r - i < 0.5 Then NuRoundNearest = i * Interval Else NuRoundNearest = (i + 1) * Interval
    11.  If Number < 0 Then NuRoundNearest = NuRoundNearest * -1 ' account for negative numbers
    12. 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)

  6. #6
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    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?

    Heh, CODE WAR!!!

    Any ways, then I Submit this single line Function:

    VB Code:
    1. Private Function ROUND_IT(ByVal MY_NUM As Single) As Single
    2. ROUND_IT = Round(2 * ((100 * MY_NUM + CDec((CBool(100 * MY_NUM Mod 5))) + 1) / 100), 0) / 2
    3. End Function
    4.  
    5. Private Sub Command4_Click()
    6. '4.48 => 4.5
    7. '4.02 => 4.0
    8. '4.95 => 5.0
    9. '.25 => .5
    10. '.26 => .5
    11. '.24 => 0
    12. MsgBox ROUND_IT(4.48)
    13. MsgBox ROUND_IT(4.02)
    14. MsgBox ROUND_IT(4.95)
    15. MsgBox ROUND_IT(0.25)
    16. MsgBox ROUND_IT(0.26)
    17. MsgBox ROUND_IT(0.24)
    18.  
    19. End Sub

    -Lou

  7. #7
    Helger
    Guest
    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

  8. #8

  9. #9
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    Making it a lot more complicated than it needs to be:

    num = round(num*2,0)/2

    enjoy!

  10. #10
    Helger
    Guest
    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

  11. #11
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    DaveAMS,
    Been There, Done That:

    Originally posted by NotLKH
    This works:

    Use a function like this:

    VB Code:
    1. MyNum = Round(2 * MyNum, 0) / 2


    -Lou
    Then Nucleus:

    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?
    Please read more than the last post, next time.

    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:
    1. Private Function ROUND_IT_2(ByVal MY_NUM As Single) As Single
    2. 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
    3. End Function
    4.  
    5. Private Sub Command4_Click()
    6. 'For both Pos & Neg Orientations
    7. '4.48 => 4.5
    8. '4.02 => 4.0
    9. '4.95 => 5.0
    10. '4.5 => 4.5
    11. '3.5 => 3.5
    12. '.25 => .5
    13. '.26 => .5
    14. '.24 => 0
    15. MsgBox ROUND_IT_2(4.48)
    16. MsgBox ROUND_IT_2(4.02)
    17. MsgBox ROUND_IT_2(4.95)
    18. MsgBox ROUND_IT_2(4.5)
    19. MsgBox ROUND_IT_2(3.5)
    20. MsgBox ROUND_IT_2(0.25)
    21. MsgBox ROUND_IT_2(0.26)
    22. MsgBox ROUND_IT_2(0.24)
    23.  
    24. MsgBox ROUND_IT_2(-4.48)
    25. MsgBox ROUND_IT_2(-4.02)
    26. MsgBox ROUND_IT_2(-4.95)
    27. MsgBox ROUND_IT_2(-4.5)
    28. MsgBox ROUND_IT_2(-3.5)
    29. MsgBox ROUND_IT_2(-0.25)
    30. MsgBox ROUND_IT_2(-0.26)
    31. MsgBox ROUND_IT_2(-0.24)
    32. End Sub


    -Lou

  12. #12

  13. #13
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    how about

    num = cdbl(cint(num*2+.5))/2
    Last edited by DaveAMS; Sep 5th, 2001 at 11:52 AM.

  14. #14

  15. #15
    Helger
    Guest
    NotLKH: No objections to any of your functions

    I only wanted to call to everybodies attention that microsoft messed up THEIR round-function.

    Helger

  16. #16
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    hmmm...cint rounds up! I always thought it truncated.

    num = Int(i * 2 + 0.5) / 2

    this should work.

  17. #17

  18. #18
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    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

  19. #19
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    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!!!


    -Lou

  20. #20
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    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...

  21. #21
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    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:
    1. Function RoundTo(Number As Double, Interval As Double) As Double
    2. Dim i#
    3. i = 1 / Interval
    4. RoundTo = Fix((Abs(Number) + Interval / 2) * i) / i
    5. If Number < 0 Then RoundTo = RoundTo * -1
    6. 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.

  22. #22
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    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).

  23. #23
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    Yes that is one solution, however, it limits you to 4dp.

  24. #24
    Lively Member
    Join Date
    Aug 2001
    Location
    Crossroads of America
    Posts
    72
    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!!!"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width