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 support@ccsinfo.com

Arithmetic error in sum of int array member and float

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



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Arithmetic error in sum of int array member and float
PostPosted: Wed Aug 31, 2011 7:17 am     Reply with quote

I have just sent in a bug report regarding an arithmetic error on PCWH 4.124 :-( This is just for people's information and if they wish to check if other complier versions show the fault.

Its a code generation error that means that a + b != b + a in some situations. It also relates to casting which is something I've been writing a fair bit about. I found this fault when trying to debug temperature compensating code for multiple channel GaAs FET bias generation, which explains the arrays of arrays. And no, I use longer, more readable variable names. I have shortened them for this test example.

Here's my test source.

Code:
#include <18F6722.h>
#device ICD=TRUE

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES EC                       //External clock with CLKOUT
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES BBSIZ1K                  //1K words Boot Block size
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads

#use delay(clock=10000000)

float T_D;
float T_C[2] = { 0.0f, 1.0f };
int D;
signed int16 V_C[2][2] = { { 4000, 4000 }, { 4000, 4000 } };
signed int16 V;

signed int16 C[2] = { 4000, 4000 };

signed int16 E = 4000;

void main()
{
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

D = 1;     
T_D = 1.0f;

      // This code shows that on PCWH 4.124 a + b != b + a if a is an integer array and b is a float.

      // This is the original form of the code where I saw the problem.
      V = V_C[0][D] + (T_D * T_C[D]);  // V should be 4000 if D = 0, 4001 if D = 1. V is always 0 :-(
     
      // Reversing the order of the sum solves the problem.
      V = (T_D * T_C[D]) + V_C[0][D];  // V should be 4000 if D = 0, 4001 if D = 1. V is correct.
     
      // Try doing it in stages.
      V = V_C[0][D];                   // V should be 4000. V is correct.
     
      V += (T_D * T_C[D]);             // V should be 4000 if D = 0, 4001 if D = 1.  V is correct.
     
      // Possibly arithmetic error is related to double indexing (2D array). So try a simple 1D array.
      V = C[D] + (T_D * T_C[D]);       // V should be 4000 if D = 0, 4001 if D = 1. V is always 0 :-(
     
      V = (T_D * T_C[D]) + C[D];       // V should be 4000 if D = 0, 4001 if D = 1. V is correct.
     
      // Both array versions had the fault. Try simple varible.
      V = E + (T_D * T_C[D]);          // V should be 4000 if D = 0, 4001 if D = 1. V is correct!
     
      V = (T_D * T_C[D]) + E;          // V should be 4000 if D = 0, 4001 if D = 1. V is correct.
     
      // Simple variable worked OK.
     
      // This is the simplest expression that shows the fault.
      V = C[D] + T_D;       // V should be 4001. V is always 0 :-(
     
      V = T_D + C[D];       // V should be 4001. V is correct.
     
      // Explicit casting solves the problem. This suggests the problem is related to
      // type determination in implicit/automatic casting.
      V = C[D] + (signed int16)T_D;       // V should be 4001. V is correct.
     
      V = (signed int16)T_D + C[D];       // V should be 4001. V is correct.

}


After all that I hope I've not done anything stupid :-(

RF Developer
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Wed Aug 31, 2011 7:24 am     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?p=76060

Came across something similar 4.5 years ago. In my case it turned out that the order of the variables/constants was important.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Sep 01, 2011 1:38 am     Reply with quote

The test program has same results with PCH V4.078, apparently it's an old bug.
Quote:
Came across something similar 4.5 years ago.

Your post also shows, that some things haven't changed much at CCS.
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