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
+ Reply to Thread
Results 1 to 11 of 11
-
-
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. -
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 -
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. -
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.
-
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. -
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 -
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. -
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.
-
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
Similar Threads
-
Help with an IF/THEN formula in EXCEL
By Rudyard in forum ComputerReplies: 4Last Post: 13th Sep 2011, 01:53 -
Output video width is not divisible by 16
By midiw in forum ffmpegX general discussionReplies: 5Last Post: 20th Jan 2011, 08:10 -
Divisible by 16?
By vid83 in forum Video ConversionReplies: 2Last Post: 30th Dec 2008, 18:46 -
Rule of 16: is a divisible height as important?
By ptfigg in forum ffmpegX general discussionReplies: 1Last Post: 11th Jul 2008, 11:48 -
Divisible by 16
By loneoak in forum ffmpegX general discussionReplies: 1Last Post: 22nd Mar 2008, 00:02