View previous topic :: View next topic |
Author |
Message |
micro_man
Joined: 05 Jun 2013 Posts: 14
|
multiplication problem |
Posted: Wed Jun 05, 2013 2:03 am |
|
|
guys its a very simple program.simply multiplying a variable with 100 and store it in another variable.but the result store in the variable is incorrect.
here is the program
Code: |
#include <18F252.h>
#FUSES HS,PUT,NOLVP,PROTECT
#use delay(clock=4M)
unsigned int8 a;
unsigned int16 b;
void main()
{
a=3;
while(1)
{
b=a*100;
}
}
|
when i see its assembly, i come to know it after multiplying the result store in two registers PRODL and PRODH, the result store in variable b is PRODL, PRODH is not in use.
what i want is,the result store in variable b is 300 not 44.
How can i do this? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Jun 05, 2013 2:10 am |
|
|
In 8 bit maths 3*100 = 44.
Exactly the result you're getting.
What's the problem?
Mike
EDIT Hint 256 + 44 = 300! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Wed Jun 05, 2013 2:22 am |
|
|
Further hint. is 100, the same as 100L in C?.
Do a forum search, you will find hundreds of answers.
Best Wishes |
|
|
micro_man
Joined: 05 Jun 2013 Posts: 14
|
|
Posted: Wed Jun 05, 2013 2:27 am |
|
|
thanks guys for your replies
are you saying that i can achieve the result by doing something like
b= PRODH*256 + PRODL;
how i search the forum, i mean what should i write in the search bar for this specific problem? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Jun 05, 2013 2:33 am |
|
|
Each of 'a' and '100' is an 8 bit value.
So the compiler has no way of knowing you want a 16 bit result from a*100.
Mike
EDIT
You have to tell the compiler you want a 16bit result.
It's done in 'C', not by playing about with registers. |
|
|
micro_man
Joined: 05 Jun 2013 Posts: 14
|
|
Posted: Wed Jun 05, 2013 2:51 am |
|
|
I have already initialized result variable b as an int16 bit.Should i also initialize a as an int16 bit? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Wed Jun 05, 2013 2:52 am |
|
|
It has been answered hundreds of times. However:
'C' works by looking at the 'types' of both arguments in an expression, and using the 'higher' type of both.
So if you take int8*int8, it uses int8 arithmetic.
However int8*int16, it uses int16. etc..
Now, 100, is an 'int8'. 'a', also is an int8, hence int8 arithmetic.
You can 'tell' the compiler, that a constant, is int16, by using 'L' (long). So 100, is an int8 constant, while 100L, is an int16. You can also 'tell' the compiler to convert a variable to a higher type before using it with a 'cast'. So
b=(int16)a*100;
tells the compiler to treat 'a' as an int16 before use. While:
b=a*100L;
tells the compiler to treat the '100' as an int16.
Now key is that in most C's the default integer type is an int16, not int8, so problems like this only appear with larger numbers. Also, on C's written for chips with hardware maths units, the unit itself handles 'overflow', and so in many cases the language will propagate the overflow condition and not clip the result. However it happens on all C's at some point or another.....
This is described in the original K&R books, and in most C textbooks, though the latter in particular tend to 'assume' int16 as the smallest maths type. K&R, gives examples with an early PDP, and 12bit as the default maths size.
Best Wishes |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Wed Jun 05, 2013 8:00 am |
|
|
Lookup function "_mul" in the CCS manual... _________________ Andrew |
|
|
|