VideoHelp Forum




+ Reply to Thread
Results 1 to 11 of 11
  1. Member
    Join Date
    Nov 2006
    Location
    United States
    Search Comp PM
    Thanks for the help.

    I'm writing some code for a video application and I need to implement a calculation that returns the nearest number evenly divisible by 16 based on a user defined input. The concept is similar to the alert message that appears in ffmpegX when the output width is not evenly divisible by 16

    For example: if the input number is 188 ... the calculation would return 192 ... etc.

    Can someone help me with the formula?

    Thanks.

    -ptf
    Quote Quote  
  2. You don't say which language you are writing in but this is the general method:

    1. divide the number given by 16 and take the integer result (188 / 16 = 11) this gives the nearest LOWER denominator.
    2. add 1 to the number you got in the first step and multiply it by 16, this gives the next HIGHER multiple.
    3. which ever is closest to the original number is the value you want. Multiply this by 16 to get the result.

    For example: 188/16 = 11,
    11*16 = 176 (difference of 12)
    12*16 = 192 (difference of 4)

    So use 12 * 16 as the nearest value which is 192.

    Brian.
    Quote Quote  
  3. Member
    Join Date
    Sep 2002
    Location
    Washington, D.C.
    Search Comp PM
    Or if the remainder is > 8 then use the next higher number if <8 use the lower number. This saves an additional calculation. IF it is 8 then it is your choice.

    Ed
    Quote Quote  
  4. Member
    Join Date
    Nov 2006
    Location
    United States
    Search Comp PM
    Thanks guy's.

    I may need a bit more help with the code. It's a Cocoa app/Objective -C.

    Let me see if I can work this out based on what you have posted.

    Again, thanks for helping me.

    ptf.
    Quote Quote  
  5. Always Watching guns1inger's Avatar
    Join Date
    Apr 2004
    Location
    Miskatonic U
    Search Comp PM
    You need to read up on the Mod function, which will tell you the remainder of any given division. You can then do a simple comparison of the given number modded with 16 and look for 0. If it isn't, adjust and look again.

    http://www.cprogramming.com/tutorial/modulus.html

    http://www.devarticles.com/c/a/Cplusplus/First-Steps-in-C-Programming-introduction/7/
    Read my blog here.
    Quote Quote  
  6. Member
    Join Date
    Nov 2006
    Location
    United States
    Search Comp PM
    Thanks again everyone.

    As betwixt demonstrated above:

    I'll use 722 as an arbitrary input number, mManualHorizontal is the input field.

    722 / 16 = 45.125

    So I arrive at:

    45 and 46 using the following:

    (mCalculationOne.floatValue = (mManualHorizontal.floatValue / 16 ));
    (mCalculationTwo.floatValue = (mManualHorizontal.floatValue / 16 + 1));

    I'm clear on the remainder of the calculation that will ultimately express the nearest value to 722 (720).


    (mCalculationThree.floatValue = (mCalculationOne.floatValue * 16 ));
    (mCalculationFour.floatValue = (mCalculationTwo.floatValue * 16 ));


    My problem is the above is using 45 and 46 with remainders instead of whole numbers rounded down. So the formula is not working. Is this due to the fact that I am using floats? I have the Cocoa Number Formatter set to return whole numbers. No success.

    Thanks again. I'm doing my best to pick this up and I don't mean to impose.

    -ptf.
    Quote Quote  
  7. fast, all integer:

    If you want the floor: (n / 16) * 16;
    If you want to round (half rounds up): ((n + 8) / 16) * 16
    If you want the next higher (or even): ((n + 15) / 16) * 16

    The last one is useful if you want to convert a non mod16 frame into a mod16 frame with 1:1 pixel mapping + border (if necessary).

    Modern compilers are smart enough to use right shift by 4 for /16, and left shift by 4 for *16. If you have a dumb compiler you can manually specify bit shifting. For example:

    If you want to round (half rounds up): ((n + 8) >> 4) << 4
    Quote Quote  
  8. Either use the method jagabo suggests or if that isn't practical, there are two alternatives:

    1. Read the initial value as an integer and do all the calculations using integer variables, this will remove the problem of floating point fractions altogether and it will be faster.

    2. I'm not familiar with your compiler but I would imagine it has a function to take the integer part of a value and discard the fractional part. For example 123.456 becomes just 123.

    You MIGHT be able to use a cast, for example "(int)Result = (int)MyNumber/16" but I would urge caution as different compilers may produce different results, depending on how they round up or round down the parts of the calculation.

    Jagabo's suggestion on bit shifting is a good one. It would be worthwhile trying "MyNmber/16" and "MyNumber >> 4" which should give the same result if integers are used but the latter method should be much faster.

    Brian.
    Quote Quote  
  9. Readability of the code is more valuable than speed in a calculation like this (a simple calculation you're going to make once before a long operation on the data). I would use explicit multiplies and divides. As noted, the compiler will likely use bit shifts for multiplication or division by powers of 2 if it's faster.
    Quote Quote  
  10. Member
    Join Date
    Nov 2006
    Location
    United States
    Search Comp PM
    Thanks again for all the assistance.

    -ptf.
    Quote Quote  
  11. Member Cornucopia's Avatar
    Join Date
    Oct 2001
    Location
    Deep in the Heart of Texas
    Search PM
    Couldn't you just as easily look at the fractional portion as the determiner for rounding?

    Ex:

    722 / 16 = 45.125, Compare .125 <.5, so round down -> 45.
    If it were >.5, you would have rounded up to 46. Then mult 45*16 or 46*16.

    Scott
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!