View previous topic :: View next topic |
Author |
Message |
msa
Joined: 07 Apr 2010 Posts: 15
|
int32 problem |
Posted: Sun Jul 18, 2010 3:19 am |
|
|
hi all
I need to convert my message msgx="98769" to number 98769.
When I run this code give me wrong number !!!!???
Note: I use PIC18F2550 and PCH V 4.093
Thanks
Code: |
#use delay(clock=8MHZ)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,stream=PC)
unsigned int32 x = 0;
char msgx[6]="98769";
void main(void){
setup_oscillator(OSC_8MHZ);
printf("\n\r\n\r............... Welcome to PIC ...............\n\r");
x =( (msgx[0] - 0x30)* 10000) + ( (msgx[1] - 0x30) * 1000) + ((msgx[2] - 0x30)* 100) + ((msgx[3] - 0x30)* 10) + (msgx[4] - 0x30);
printf(" X = %Lu",x);
}
|
|
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sun Jul 18, 2010 5:09 am |
|
|
It would help if you told us what number it does give...
I suspect that this may be the problem:
(msgx[0] - 0x30)* 10000)
The 10000 term will cause the PIC to use 16 bit math. If the digit is a '9' the 16 bit math will overflow. You need to declare 10000 as a 32 bit number. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Jul 18, 2010 6:29 am |
|
|
Any reason not to use standard C-functions atoi() respectively atoi32()? |
|
|
msa
Joined: 07 Apr 2010 Posts: 15
|
|
Posted: Sun Jul 18, 2010 11:49 am |
|
|
hi SherpaDoug
give me number 32721
thanks |
|
|
msa
Joined: 07 Apr 2010 Posts: 15
|
|
Posted: Mon Jul 19, 2010 12:47 am |
|
|
thanks FvM
i solved my problem by using function atoi32
x= atoi32 (msgx); |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19500
|
|
Posted: Mon Jul 19, 2010 1:55 am |
|
|
Just to explain, in case you do decide to go DIY in a similar situation in the future.
You have five 'terms':
9
6*10 =60
7 * 100 - first problem both the digit, and the multiplier are 8bit integers 7*100 = 700, overflows an 8bit integer to give 188
8*1000 = 8000 -since 1000 is bigger than 255, the maths switches to 1nt16, so this is OK
9*10000 =90000- second problem - system now selects int16 arithmetic, and as SherpaDoug points out, this will overflow, giving 24464
24464+8000+188+60+9 = 32721....
To work reliably, you would need to force the use of int32 arithmetic for the top term, and int16 arithmetic for the third term. So:
Code: |
x =( (msgx[0] - 0x30)*(int32)10000) + ( (msgx[1] - 0x30) * 1000) + ((msgx[2] - 0x30)*(int16)100) + ((msgx[3] - 0x30)* 10) + (msgx[4] - 0x30);
|
Throughout your code, you have to remember when multiplying, that if the result may not fit into the type being used by the source numbers, you must explicitly force the use of a larger type.....
The int32 in the top term here will also force the final sum to be done in int32 arithmetic avoiding the same problem coming at this point....
Best Wishes |
|
|
|