C++ rounding to nearest multiple of 5

Discussion in 'Programming & Software Development' started by ring wraith, Mar 6, 2006.

  1. ring wraith

    ring wraith Member

    Joined:
    Jan 18, 2002
    Messages:
    2,120
    Location:
    A.K.A Frank
    Another question regarding C++ :p

    now theres 2 ways Im thinking I can do this. first, there's a magical function in C that does ALL this for me, something like round(74, 5) (74 to the nearest multiple of 5). this is probably unlikely...

    the other is to do some sort of conditional loop where X is the number to round, I was thinking of doing an increment until the number is a multiple of 5 and stop there. the only problem being how to determine which way the increment would go if its a 2 or 3 digit number. any ideas on how else to do this without an increment? somehow use Fmod() or % to figure it all out.
     
  2. HeXa

    HeXa Member

    Joined:
    Jul 7, 2001
    Messages:
    10,216
    Location:
    Canberra, ACT
    round(n/5)*5

    EDIT: that was from memory.... think thats what I learnt in 1st year IT :p I forget the exact behaviour of round() so you might need to play around a bit.

    - HeXa
     
    Last edited: Mar 6, 2006
  3. 3t3rna1

    3t3rna1 Member

    Joined:
    Dec 24, 2001
    Messages:
    1,452
    Location:
    Perth
    Something like
    Code:
    int round(double number, int round) {
      return number - (number % round)
    }
    would return a rounded down result. You could add an conditional part to make it round up if its closest to the next multiple of 5. EG
    Code:
    int round(double number, int round) {
      if((number % round) =< (round / 2)) return number - (number % round)   //Round down
      else return number - (number % round) + round   //Round down, then up again 
    }
    It should work... I'm not a much of a programmer though :(

    EDIT: damn syntax
     
  4. camh

    camh Member

    Joined:
    May 23, 2002
    Messages:
    140
    Location:
    Sydney
    If n is an integer, ((n+2)/5)*5 will do it.
     
  5. turbovan

    turbovan Member

    Joined:
    Feb 28, 2003
    Messages:
    28
    Location:
    Sydney
    n - (n % 5)

    will round it down to nearest 5
     
  6. blaqDeaph

    blaqDeaph Member

    Joined:
    Jul 27, 2004
    Messages:
    1,155
    Location:
    127.0.0.1
    That'd round it down. You'd need something like

    number % 5 < 3 ? number - (number % 5) : number - (number % 5) + 5

    will round it up or down depending on the number.
     
  7. green

    green Member

    Joined:
    Dec 12, 2003
    Messages:
    367
    doesn't the /5 and *5 just cancel out to give you n+2?
    or am i reading that wrong...
     
  8. blaqDeaph

    blaqDeaph Member

    Joined:
    Jul 27, 2004
    Messages:
    1,155
    Location:
    127.0.0.1
    Note the brackets and note that division of integers will return a integer result which is then multiplied by 5
     
  9. camh

    camh Member

    Joined:
    May 23, 2002
    Messages:
    140
    Location:
    Sydney
    Since we are dealing with integers, the /5 and *5 will not cancel each other out.

    0/5 = 0
    1/5 = 0
    2/5 = 0
    3/5 = 0
    4/5 = 0
    5/5 = 1
    ...
     
  10. Bradzac

    Bradzac Member

    Joined:
    Aug 17, 2003
    Messages:
    1,744
    Its in c#, should be very easy to port over to c++. I would have written it in c++ but cbf :p. You're free to do whatever you want with it ;)


    Code:
    private static void RoundNumber(int x)
            {
                int n , i;
                n = x / 10;
                i = n * 10;
    
                //First check that the number needs to be rounded
    
                if ((x-i) != 0)
                {
                    //If the number needs to be rounded and
                    //and it is less then #5, round it down
                    if ((x - i) < 5)
                    {
                        //Tell the user you are rounding down
                        Console.WriteLine("Round down");
                        //Round the value down
                        x = x - (x - i);
                        //Display the rounded value
                        Console.WriteLine(x);
                    }
                    else
                    {
                        //otherwise if the number is greater
                        //then #5, round it up.
    
                        //Tell the user you are rounding up
                        Console.WriteLine("Round Up");
                        //Round the value down
                        x = x + (10 - (x - i));
                        //Display the rounded down value to 
                        //the user
                        Console.WriteLine(x);
    
                    }
                }
                else //the number is #0, so nothing needs to be done
                {
                    //do nothing
                    Console.WriteLine("X Doesnt need to be rounded");
    
                }
    
    
            }
     
  11. Rolan

    Rolan Member

    Joined:
    Jun 27, 2001
    Messages:
    330
    Location:
    Sydney
    and the round function in its naked form
    Code:
    int round (double x, float nearest )
    {
        float _nearest = nearest;
        int i;
        __asm
        {
            fld x
            fadd st, st (0)
            fadd _nearest
            fistp i
            sar i, 1
        }
        return i;
    }
    
    to round to nearest integer, nearest = 0.5f
     
    Last edited: Mar 10, 2006
  12. green

    green Member

    Joined:
    Dec 12, 2003
    Messages:
    367
    ahhh yea makes more sense now
    so should read a more like like

    ((int)((n+2)/5))*5

    was thinking the division by 5 would inherently typecast to float
     
  13. GregDude

    GregDude Member

    Joined:
    Aug 12, 2002
    Messages:
    1,303
    Location:
    Brisbane
    Here's a snip of code from my math library. These functions are not optimized:
    Code:
    // Round toward positive infinity grid boundary.
    float RoundPosInfGrid(float a_val, float a_gridRes)
    {
      float div;
    
      div = a_val / a_gridRes;
      a_val = ceil(div) * a_gridRes;
    
      return a_val;
    }
    
    // Round toward negative infinity grid boundary.
    float RoundNegInfGrid(float a_val, float a_gridRes)
    {
      float div;
    
      div = a_val / a_gridRes;
      a_val = floor(div) * a_gridRes;
    
      return a_val;
    }
    
    // Round to nearest grid boundary
    float RoundNearestGrid(float a_val, float a_gridRes)
    {
      float negRnd, posRnd;
      float negDif, posDif;
      float div;
    
      div = a_val / a_gridRes;
      negRnd = RoundNegInf(div) * a_gridRes;
      posRnd = RoundPosInf(div) * a_gridRes;
     
      negDif = fabsf(a_val - negRnd);
      posDif = fabsf(a_val - posRnd);
    
      if( negDif < posDif )
      {
        return negRnd;
      }
      else
      {
        return posRnd;
      }
    }
    
     
  14. blaqDeaph

    blaqDeaph Member

    Joined:
    Jul 27, 2004
    Messages:
    1,155
    Location:
    127.0.0.1
    Thats the beauty of C++. It performs operations based on the original type of the value that is being operated on. This means that if n were defined as an integer, the result will always be an integer, unless type casted otherwise.

    so,
    Code:
    int n = 23;
    cout << n / 5;
    
    would print 4

    but

    Code:
    int n = 23;
    cout << (float)n / 5;
    
    would print 4.6
     
  15. mordy

    mordy Member

    Joined:
    Aug 30, 2001
    Messages:
    5,100
    Location:
    melb
    um, why cant u do this with plain integer maths

    ((int) number/5 ) *5 .. should do the rounding up and down based on what the original number was
     
  16. houseofzeus

    houseofzeus Member

    Joined:
    Mar 25, 2005
    Messages:
    3,195
    Location:
    St. Lucia, Brisbane
    By casting to int you have already discarded any floating point information held in number.
     
  17. Pacifist

    Pacifist Member

    Joined:
    Mar 10, 2002
    Messages:
    1,949
    Location:
    Gosford
    No his basic idea is right although it wouldn't work for a different reason...
    eg. 26/5 = 5 as an integer (you don't want it as a float)
    Now times by 5 and you have 25, the correct answer :)


    Unfortunatly C always rounds integers down, so 29/5 in C/C++ actually gives 5 which is wrong.
     
  18. Kermalius

    Kermalius Member

    Joined:
    Mar 15, 2002
    Messages:
    870
    n = number,
    f = factor to round to (ie. 5)

    ((int) n / f) * f == n - n%f; gives rounded down

    so:

    r = n%f; (n - r) + (r >= f/2 ? f : 0) gives rounded to nearest factor when done in ints.

    if f = 6, f/2 = 3, and we want r = 3 to be rounded up (r in {0,1,2} = down, {3,4,5} = up), and
    if f = 5, f/2 = 2.5 = 2, and we want r = 2 to be rounded up (r in {0,1} = down, {2,3,4} = up).


    Same line will work for floats, but to be on the safe side, it might be easiest to swap r >= f/2 for r-(f/2) >= (f/2)/10E-8 and define only safe for f > 10E-7 or similar. I'm to lazy to figure out if there's potential for an IEEE 754 issue in this one.
     
  19. houseofzeus

    houseofzeus Member

    Joined:
    Mar 25, 2005
    Messages:
    3,195
    Location:
    St. Lucia, Brisbane
    No, it isn't. When he casts to int the floating point information is dropped, the fact that it happens to work when you need it to round down (but never when you need to go up) does not make it the right idea.

    This isn't a different reason, dropping the floating point information and rounding down are the same thing for all intents and purposes.
     
  20. Pacifist

    Pacifist Member

    Joined:
    Mar 10, 2002
    Messages:
    1,949
    Location:
    Gosford
    There are 2 seperate problems with his example.
    He casts the float number to an int, that float would be rounded down (could be a problem if the float is 27.55f).

    Secondly he did an integer/integer operation, which again always rounds down.
    eg.

    int i = 29;
    int j = 5;
    int k;
    k = i / j; // K now equals 5

    Note the above has no floating point involved and it has nothing to do with float to integer truncation, integers always round down on division.
     

Share This Page

Advertisement: