I am using a PIC16f877 and CCs compiler. Is there a maths function that will enable me to calculate 50% of an integer variable in a register and store the answer in another variable, or would I calculate it myself.
Also is an integer 8 bit or 16 bit long. some books say it is 8bit and others 16 bit.
Dean Matthews
Reliability Engineering
Ford Engine Plant Bridgend
Waterton industrial estate
cf31 3pj
South Wales, U.K
Tel No: 0044(1656)672597
Fax No: 0044(1656)672558
Email: spam_OUTdmatth14TakeThisOuTford.com
Room 25/118
` Please consider your environmental responsibility before printing this e-mail
If its always 50% then just divide by 2, which is efficiently implemented by
a right shift by one bit. CCS-C should optimise it to a rotate right
operation.
int Val, Result;
Result = Val / 2;
if the percentages change then you will need to change that to multiply by
100 then divide by the percentage. Note - be careful you don't over run the
integer. You need to do the multiply first.
In CCS-C the "int" type by default is 8 bits. This is always compiler
dependant, if you want to make sure of the size your using try using int8,
int16 and int32 as the types.
So if you had a 8 bit number and you wanted to get an arbitrary percentage,
you would need to promote it to a 16 bit number so you don't overflow it
int8 Val, Result;
int8 Percent;
int16 temp;
temp = (int16) Val * 100;
temp = temp / Percent;
Result = (int8)temp;
the type in brackets is a cast to that type of the following identifier.
> I am using a PIC16f877 and CCs compiler. Is there a maths
> function that will enable me to calculate 50% of an integer
> variable in a register and store the answer in another
> variable, or would I calculate it myself.
I may be missing something here, but is there a problem with doing a right
shift? Or are you looking for something more generalised than /2 ?
> Also is an integer 8 bit or 16 bit long. some books say it
> is 8bit and others 16 bit.
"It depends on the compiler" is the short answer. I'm assuming here that if
you're referring to integer types, you are using a compiler...
With the stuff I more normally use (gcc on 860s), an int is 32 bit, a short
int 16 and a byte (usually defined as an unsigned char) is 8 - but, for
portability, you should never depend upon those being consistent.
This has been discussed before IIRC - perhaps a search of the archives would
help?
Peter
This email, its content and any attachments is PRIVATE AND CONFIDENTIAL to
TANDBERG Television. If received in error please notify the sender and
destroy the original message and attachments.
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
Richards, Justin P (and others providing the same answer) wrote :
>50% if that is the same as a half then right shifting the register will
give
>you 50% of what you had before.
>Hope thats what you were after
Well this is ofcource correct, however there is an issue with rounding. As
this
would truncate the result, i.e. 2->1, 3->1, 4->2 etc.
If 'normal' rounding is to be taken into account i.e. 0.5 is rounded to 1
0.4 is rounded to 0, you also need to:
check lowest bit of number, if '1' then add one to number *then* divide by
two
( right shift by one ).
nit picking yes, but could be an issue.
/Tony
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
>Well this is ofcource correct, however there is an issue with rounding. As
>this
>would truncate the result, i.e. 2->1, 3->1, 4->2 etc.
There's also an issue if the number is negative. In the case of a 2's
complement number, you have to duplicate the sign bit if you are
doing an arithmetic right shift. The PIC doesn't have a specific
instruction for this, but you can left shift with W as the destination
to shove the sign bit into the carry, then right-shift the carry in.
For unsigned numbers, of course, you'd just clear the carry first.
> check lowest bit of number, if '1' then add one to number *then* divide by
> two
You don't need to check if the low bit is 1. Simply add 1. This will
generate a carry into the rest of the number if the low bit was one. Of
course you now have to worry about the original number being at maximum.
You either have to check this, or add one to the *shifted* number if the
original low bit was 1.
However, in most cases truncation is either fine or is actually what you
want.
********************************************************************
Olin Lathrop, embedded systems consultant in Littleton Massachusetts
(978) 742-9014, olinspam_OUTembedinc.com,http://www.embedinc.com
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
OK, I see that you're using C. In that case you should use /2 if the
number is signed. Shifting (>>1) should be avoided because the results
are officially "implementation defined", thus it is non-portable code.
See: ISO/IEC 9899:1999 (E) 6.5.4 (the current C standard)
A few more abbreviations:
www.physik.uni-stuttgart.de/ExPhys/2.Phys.Inst./member/b.nebendahl/ab
br.html
Peter
This email, its content and any attachments is PRIVATE AND CONFIDENTIAL to
TANDBERG Television. If received in error please notify the sender and
destroy the original message and attachments.
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads