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

Math issue

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



Joined: 22 Sep 2003
Posts: 101
Location: Cape Town (South africa)

View user's profile Send private message Send e-mail Visit poster's website

Math issue
PostPosted: Wed Mar 14, 2007 8:06 am     Reply with quote

When the value of m3 is multiplied by 100 before being added to the variable then strange things happen under certain circumstances. If the value of m3 = 2 then it is ok but if the value of m3 is 3 then it gets very confused.

m1,m2, m4 all seem fine

if m3 is not multiplied by 100 then all is ok.

if m3 = 3 and multiplied by 100 then the answer is 44
if m3 = 4 and multiplied by 100 then the answer is 144
if m3 = 5 and multiplied by 100 then the answer is 244


The data does come through correctly from the PC

Pic side
---------
Code:
   
  float XdroPos=0;
  float m1=0;
  float m2=0;
  float m3=0;
  float m4=0;


if (usb_enumerated()) {
      if (usb_kbhit(2)) {
         usb_get_packet(2, rx_data, 8);

         if (rx_Data[0]==2) { // DRO
           if (rx_Data[1]==0) { // X DRO         

             m1 = rx_Data[4] & 0x0F; // blank off the high byte
             XdroPos = m1;
                         
             m2 = (((rx_Data[4] & 0xF0) >> 4)*10); // blank off the low byte                                       
             XdroPos = XdroPos + m2;

             m3 = ((rx_Data[3] & 0x0F)*100); // blank off the high byte
             XdroPos = XdroPos + m3;
             
             m4 = (((rx_Data[3] & 0xF0) >> 4)*1000); // blank off the low byte
             XdroPos = XdroPos + m4;
                                                                 
             if (rx_Data[2]=='-')
               XdroPos = XDroPos * -1;
               
             printf("m1 %09.4f m2 %09.4f m3 %09.4f m4 %09.4f  X DRO %09.4f ",m1,m2,m3,m4,XdroPos);
           } 
         } 

//         printf("Data Endpoint 2: ");

//         for (i=0;i<=7;i++)
//           printf("%C ",rx_data[i]);
//           printf("0x%X ",rx_data[i]);


PC side
---------
Code:
OutputReport[0]= 0;         //this is just a report number, always zero

// lets update the X dro
CncCSDRO = GetDRO(800);
 sprintf(CncCSDROBuffer, "%09.4f",abs(CncCSDRO)); // make sure that the - does not move the string about
      
// test the data move to the handheld
OutputReport[1] = 2;      // DRO report
OutputReport[2] = 0;      // X DRO

if (CncCSDRO>0)
  OutputReport[3] = '+';
else
  OutputReport[3] = '-';
      
OutputReport[4] = ((CncCSDROBuffer[0]-48) <<4) + (CncCSDROBuffer[1]-48); // take ascii back to a number
OutputReport[5] = ((CncCSDROBuffer[2]-48) <<4) + (CncCSDROBuffer[3]-48); // take ascii back to a number
OutputReport[6] = ((CncCSDROBuffer[5]-48) <<4) + (CncCSDROBuffer[6]-48); // take ascii back to a number
OutputReport[7] = ((CncCSDROBuffer[7]-48) <<4) + (CncCSDROBuffer[8]-48); // take ascii back to a number
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 8:30 am     Reply with quote

Instead of multiplying by 10, 100 or 1000 try 10.0, 100.0 and 1000.0. Since they are multiplying floats things might get confused if you're multiplying a float by and integer.

Ronald
hillcraft



Joined: 22 Sep 2003
Posts: 101
Location: Cape Town (South africa)

View user's profile Send private message Send e-mail Visit poster's website

Ronald- Cured
PostPosted: Wed Mar 14, 2007 8:45 am     Reply with quote

Hi Ronald,

Thanks, the problem is now cured.
Ttelmah
Guest







PostPosted: Wed Mar 14, 2007 9:21 am     Reply with quote

Not a case of 'getting confused', but exactly what you would expect!...
Presumably 'rx_data', is declared as an integer, or character array. Hence the multiplication will be done using this arithmetic type.
You could save significant time, by using (for example):

m3 = ((int16)(rx_Data[3] & 0x0F)*100); // blank off the high byte

Which will convert the value to an int16, and perform the arithmetic with this (whereas changing to 100.0, will force floating point arithmetic). The difference, is between 3.2uSec for the int16 multiply, and 35.8uSec for the float (on a 40MHz PIC18).

Best Wishes
hillcraft



Joined: 22 Sep 2003
Posts: 101
Location: Cape Town (South africa)

View user's profile Send private message Send e-mail Visit poster's website

(int16)
PostPosted: Wed Mar 14, 2007 9:43 am     Reply with quote

Fair enough. I did not realize that by not using (int16) that I would get an error on only one digit if that digit is bigger than 2.

What about the folliwng X 0.1, 0.01, 0.001, 0.0001

This is what the entire number looks like:
-9999.9999

Code:
             XdroPos = (rx_Data[6] & 0x0F)*0.0001; // blank off the high byte
             XdroPos = XdroPos + (((rx_Data[6] & 0xF0) >> 4)*0.001); // blank off the low byte                                       

             XdroPos = XdroPos + (rx_Data[5] & 0x0F)*0.01; // blank off the high byte
             XdroPos = XdroPos + (((rx_Data[5] & 0xF0) >> 4)*0.1); // blank off the low byte                                       

             XdroPos = XdroPos + (rx_Data[4] & 0x0F); // blank off the high byte
             XdroPos = XdroPos + (((rx_Data[4] & 0xF0) >> 4)*10.0); // blank off the low byte                                       

             XdroPos = XdroPos + ((rx_Data[3] & 0x0F)*100.0); // blank off the high byte
             XdroPos = XdroPos + (((rx_Data[3] & 0xF0) >> 4)*1000.0); // blank off the low byte
Ttelmah
Guest







PostPosted: Wed Mar 14, 2007 2:21 pm     Reply with quote

Series of choices.
1. Just do the decimal ones using FP.
2. Don't store the number like this, but *1000, in an int32. Then you can use int3 arithmetic throughout, and the %w option to print it as if it was 1/1000th the size (scaled integer working).

Best Wishes
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