![]() |
How does division work?
Hey all,
I feel really dumb asking this question, but since I don't have a programming mentor I must rely on what I read, and the community. Since I don't know what to search for ("division" brought up tons of non-related posts...what else should I search for?) I am just going to post this. Sorry if it's a repeat. If I'm using all integers, how will the RC calculate these: 30/7 = (It rounds to 4, so I assume I'd get 4) 70/6 = (This is where I'm confused...it's 11.6666..., but will the robot round it, or take the floor? Meaning, do I get 12, or 11? I don't have the hardware in front of me to experiment with...) Thanks for helping with a n00b question...:o JBot |
Re: How does division work?
If you are typecasting a float to an int. Such as
Code:
int i = (int) (70/6) |
Re: How does division work?
It will truncate the numbers after the decimal point.
|
Re: How does division work?
If you need the extra places the most efficient way to do it will be to bit shift the dividend, and remember that any time you need to do a calculation, you need to bit shift the result back. using bit shift instead of multiplying by something like 10 will save you a few clock cycles.
multiplication 8-bit by 8-bit method (if you multiply by an arbitrary value such as 10) see here http://www.dcc.unicamp.br/~celio/mc4...los/mul8x8.asm Program Memory : 14 locations # of cycles : 71 RAM : 5 locations That is a really big waist bit shift method c equivalent x<<1; can be done with the single asm command lrol (load and rotate left) |
Re: How does division work?
Quote:
|
Re: How does division work?
I never use signed vars (why would i want to limit my self to a predetermined split), so this is not a problem that i face. Still implementing a macro or function to do this is would be much more efficient then that multiplication nonsense.
I could see how there might be issues with signed vars. seeing as it is spans 16 bits and has to manage the split, it would have to do some interesting stuff to move that all around, and not end up shoving data in to the + side. I would have to look at the asm and memory sim to see what is actually happening (when are they going to get some real debugging tools to work with these). Anyway while on this topic people might find this of interest. http://www.microchipc.com/Hi-Tech_C_speed_optimization/ I am a little paranoid when it come to data size and clock cycles if you could not tell. EDIT: fyi the shift you have to do for signed is called Arithmetic Shift. |
Re: How does division work?
Quote:
type int: The computer will basically divide it as many times evenly into whole number, not part of a whole, and not one more. Since all the computer knows is zeros and ones, at least for type int, it sticks to its whole number interpretation, and fills what it can. Thus your 70/6 goes to 11... along with 66/6, 67, 68, 69, and 71/6. 72/6 will of course yield 12 though. (Truncation, not rounding... be careful about this difference) Once you get into type double and float (i think), then the computer believes it can handle decimals, and it will give you decimal answers. Side note somewhat related: The modulus (%) operator is amazingly useful if you want to find the remainder, for that is what it does. Its even more useful for determining if a given integer is odd or even given you divide by 2 (Example: 66 % 2 gives you 0 since it is even, 65 % 2 gives you 1 since it is odd). So if I were to run through that above problem again, this time with modulus: 66 % 6 = 0 67........= 1 68........= 2 69........= 3 70........= 4 71........= 5 72........= 0 Have fun... and never be afraid to ask questions after a search goes nowhere. -Joe |
Re: How does division work?
Quote:
I would warn against using this for the reasons outlined before (granted it *should* work)... The key reason being that you as a programmer really shouldn't have to worry about things like that as it is the compilers problem. Most compilers are written so that operations are optimized (for special cases like the one above). Unless you are writing hardware drivers you don't need to worry about assembly level optimization. Even hardware shaders (which are run directly on graphics cards) are now written in a C-like language rather than in assembly like before. |
Re: How does division work?
Quote:
|
Re: How does division work?
Quote:
Bitwise AND ands together each binary digit of the two inputs. 4 & 1 = 0 5 & 1 = 1 6 & 1 = 0 Binary example: 5 & 1: 0011 <-- 5 0001 <-- 1 0001 <-- 5 & 1 |
Re: How does division work?
Quote:
Still, I must agree that with embedded systems where there is extremely limited CPU/Memory that stuff does count. |
Re: How does division work?
Just to throw in my two cents here:
first for the OP - integer division ALWAYS truncates (at least it does it most of the major languages in use today). If you need more significant digits, by far the easiest solution is to typecast your variables (both the divisor and the dividend) - int a=1; int b=2; float c=((float) a)/((float) b); gives you c = 0.5. Second, to the discussion on bitwise operations and performance: For these robots, you really don't need to be that concerned with performance. If you follow the KISS (keep it simple, stupid) strategy, you're code won't be long enough of complicated enough to make performance an issue. When it comes to the robot controller, the difference between doing something one way or another might be a few milliseconds, but the human operator is only operating on the scale of seconds, so the level of performance you might gain is going to be lost, unless you've made your code overly complex. Last year, our code was probably two-three times more complex than it needed to be, because we were using it as a teaching tool more than anything else, and the same thing will be true this year. Even with that, though, there was absolutely no detectable performance degradation to the robot. Yes, in some systems performance really does matter - i remember back in school making an AI for class and fine tuning everything, down to the point where each game state was sized to exactly fit into the processor cache and using optimizations for the specific brand/model of the processor being used, and in that case it did pay off in noticeable quantities. It's good as a programmer to be aware of performance, and even to be aware of the performance characteristics of the libraries you're using, but you also need to know when you need to apply that knowledge and when you don't. |
Re: How does division work?
If you add 0.5, it will "round" to the nearest integer:
int x = (int)(40/9 + 0.5); // 40/9 = 4.444 repeating and rounds down to 4 int y = (int)(40/6 + 0.5); // 40/6 = 6.666 repeating, rounds up to 7 |
Re: How does division work?
Quote:
Code:
174: var1 = (int)((40/6)+0.5);Code:
175: var1 = (int)((40+(6/2))/6);If you try this with variables in the formula instead of constants, then the compiler can't figure out the answer at compile-time and generates the necessary code to figure this out at run-time. Adding 0.5 may cause conversion into and out of floating point which are really slow operations. A more correct integer based answer would be: Code:
var1 = ((var2*10)+(divisor*10)/2))/(divisor*10);However, in the case of an odd divisor such as 9, the remainder can only be 4 or 5 - not 4.5. So this suggests the simplier form below of should yield the correct answer: Code:
var1 = ((var2+(divisor/2)) / divisor;(40+(9/2)) / 9 = 44 / 9 = 4 (40+(6/2)) / 6 = 43 / 6 = 7 or did I mess up... again... |
Re: How does division work?
Quote:
Instead, what you can try (for your example) is the following: int x = (int)(40.0/9.0 + 0.5); // 40/9 = 4.444 repeating and rounds down to 4 int y = (int)(40.0/6.0 + 0.5); // 40/6 = 6.666 repeating, rounds up to 7 by adding the ".0" to the divisor and the dividend, you turn the division into a floating point operation, instead of an integer operation. That means that it won't truncate the result of the division, only the final result of the equation as you stick it into an integer. To accomplish this using variables instead of straight numbers, by far the easiest way is to typecast the variables: int x = (int)(((float)dividend)/((float)divisor) + 0.5); That tells the compiler that, for this one instance, you want it to treat the variables as floats instead of integers, meaning that it won't truncate any results in mid-computation. |
| All times are GMT -5. The time now is 23:18. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi