View previous topic :: View next topic |
Author |
Message |
nailuy
Joined: 21 Sep 2010 Posts: 159
|
Mathematics |
Posted: Sat Nov 24, 2018 2:48 am |
|
|
Hi,
I use PIC16F886 with 3 digits on 7 seg for output display and for input keys multiplexed 10 in total from 0-9.
I want to know why my number made with little math is not working well.
I found solution for helping in math but in my opinion is improvisation.
Code: |
if (TST[0]>2){
VAR=VAR+256;
}
if (TST[0]>5){
VAR=VAR+256;
}
if (TST[0]>7){
VAR=VAR+256; |
without this code until 299 is working well, at 300 show 044, and insted of 301 show 045, ...and continue as well at 699...700
Code: |
///in *.h
static unsigned int16 VAR;
static unsigned int8 TST[3];
/////////////////////////////////
//cutting in program
/////////////////////////////////
// DISP[2]=TST[2]; //for testing
// DISP[1]=TST[1]; //for testing
// DISP[0]=TST[0]; //for testing
VAR=TST[0]*100;
VAR=TST[1]*10+VAR;
VAR=TST[2]+VAR;
if (TST[0]>2){
VAR=VAR+256;
}
if (TST[0]>5){
VAR=VAR+256;
}
if (TST[0]>7){
VAR=VAR+256;
MMM=VAR;
DISP[0]=MMM/100; //for disp1
DISP[1]=(MMM/10)%10; //for disp2
DISP[2]=MMM%10; //for disp3
///////////////////////////////////////////////////////////
//end prog. |
THANK YOU! |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Sat Nov 24, 2018 3:44 am |
|
|
Hi!
Here are some ideas:
1. use your debugger or simulator and step through the code to see at what point the code is not working well.
2.
Code: | static unsigned int16 VAR;
static unsigned int8 TST[3];
VAR=TST[0]*100; |
maybe the compiler decides to work at 8 bit math.
Instead try:
VAR=(int16)TST[0]*100; |
|
|
nailuy
Joined: 21 Sep 2010 Posts: 159
|
Case solved |
Posted: Sat Nov 24, 2018 4:39 am |
|
|
dear Guy
you are right
VAR=(int16)TST[0]*100; is solution. Compiler is working like is int8 because variable is declared as int8.
may be if I can declare an variable like int4 I use because that is necesay for me.
Now is working without "improvisation"
Thank you GUY
have nice day. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Nov 24, 2018 8:36 am |
|
|
You can make a 4bit 'component part' using bitfields, but remember that the
chip fundamentally works in bytes, so two would have to be declared together
in a byte, and accessing these will be less efficient than accessing the byte
itself.
The C 'rule' on types, is that when any maths operation is used, the maths
'type' will be that of the highest type in the operation. So:
int8*int8 -> int8 maths
int8*int16 -> int16 maths
int16*int16 -> int16 maths.
int32*int8 -> int32 maths
etc. etc..
Some compilers/chips will explicitly support overflows. So on the PC for
example, if the maths is performed using the maths co-processor it'll
automatically be using a larger type always for the maths.
You could have made the operation work, with simply:
VAR=TST[0]*100L;
The 'L' here says that this '100' constant, is a 'long' (int16) constant, not
an int8.
Explicitly casting up is the other way to go. |
|
|
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Sat Nov 24, 2018 10:55 am |
|
|
yes Ttelmah.
your solution:
VAR=TST[0]*100L;
is also working and is using less RAM than:
VAR=(int16)TST[0]*100;
Thank you both for your little help.
For me both solutions are good and I understand why the compiler and the processor think so. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Nov 24, 2018 11:09 am |
|
|
Yes. The reason it saves a little memory, is that the 100L, is stored as a long constant in the code, so doesn't have to be converted up to be 16bit. With the cast, both values have to be converted at runtime. Saves a little time and RAM. |
|
|
|