View Single Post
  #9   Spotlight this post!  
Unread 09-01-2008, 10:41
dcbrown dcbrown is offline
Registered User
AKA: Bud
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Hollis,NH
Posts: 236
dcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud of
Re: How does division work?

Quote:
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
Tried this in C18 and the compile still comes up with the wrong answer.


Code:
174:                   var1 = (int)((40/6)+0.5);
 04464    0E06     MOVLW 0x6                                   << compiler gens 6
 04466    0101     MOVLB 0x1
 04468    6FE6     MOVWF 0xe6, BANKED
 0446A    6BE7     CLRF 0xe7, BANKED
Instead the following will generate the expected results:

Code:
175:                   var1 = (int)((40+(6/2))/6);
 0446C    0E07     MOVLW 0x7                                     << compiler gens 7
 0446E    6FE6     MOVWF 0xe6, BANKED
 04470    6BE7     CLRF 0xe7, BANKED
The above is the same as adding .5 to the end result, just before the actual division.

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);
This changes the floating point .5 into an integer 5 and preserves precision. Or you can roll your own integer divide routine and add in rounding based upon the remainder being larger than half the divisor.

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;
In the examples:
(40+(9/2)) / 9 = 44 / 9 = 4
(40+(6/2)) / 6 = 43 / 6 = 7

or did I mess up... again...

Last edited by dcbrown : 09-01-2008 at 10:46.