CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Trouble with 16 and 32 bit math

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

Trouble with 16 and 32 bit math
PostPosted: Fri Dec 17, 2010 4:03 am     Reply with quote

1. I am getting different results from the rr1 and rr2 variables.
The values I see when running through the code to a breakpoint show the results listed in the comments.
Why is the calculation for rr1 incorrect?
What am I missing?

2. When I first started debuging this code as an example, the 2nd assignment to o[0] resulted in 0 in the watch window.
Shouldn't the result from the two o[0] statements be identical?
Later, the results appear the same; and I can't recreate the alternate circumstances.

Thanks in advance.
Leef_me
Code:

#include "18F26K20.h"

#device ICD=TRUE
#FUSES NODEBUG                  //No Debug mode for ICD

#fuses INTRC_IO                 //Internal Oscillator, free RA6 and RA7 for i/o operations
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=16000000) //16mhz

void main(void)
{
   int8 temp;

   signed int32 rr1,rr2;
   static signed int16 c[] = {11059};
   signed int16 o[1];

        o[0]=2748;   // <---- are these the same ?
        o[0]=2748L;  // <---- are these the same ?


         rr1 = o[0] * c[0];  // <---- wrong math   result is 4294948724


         rr2 = o[0];      // <--- correct math
         rr2 = rr2 * c[0];   // <--- correct math  result is 30390132

   temp++;
   temp++;  // just a place to add a breakpoint
   temp++;

}

Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Fri Dec 17, 2010 4:17 am     Reply with quote

Exactly what would be expected.....

_Standard C_. In C, the compiler looks at what values are given for both 'sides' of an arithmetic operation, and uses the arithmetic 'type' defined by the 'higher' of these. In:

rr1 = o[0] * c[0];

Both of the variables each side of the '*', are signed int16, so signed int16 arithmetic _will_ be used, and overflow. This will then be cast to an int32 result, and will be wrong.

In the second case, rr2, is a signed int32, so the arithmetic type will change to signed int32, and no overflow results.

rr1 = (signed int32)o[0] * c[0];

This will convert the first value to a signed int32, and thereby make the compiler use this as the arithmetic type.

The problem is being caused by _you_ not thinking 'how big might the result be', and ensuring the right maths type is used.

You may get away with this error on a lot of later C's, on things like the PC, since here the maths will be done using the hardware, which handles overflows automatically (in some cases....). However to be safe, you should _always_ ensure that the maths type used is able to handle the values needed.

2748, and 2748L are the same. The 'L' forces a value to be treated as a 'long', when it is not 'obvious' from the number involved. So:

123L, is in hex 0x007B, while:

123, is 0x7B

Note the extra leading zeros. The 'L' is forcing the value to be treated as a 16bit value. However if the number is over 255, such treatment is 'automatic'.

Best Wishes
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Fri Dec 17, 2010 4:57 pm     Reply with quote

Much thanks Ttelmah. Smile

I'm a bit rusty in the area. Embarassed My prior code has been all one type.

If it help anyone else, here is a useful link.
http://www.learncpp.com/cpp-tutorial/44-type-conversion-and-casting/
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group