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

Big problem with simple math operation

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



Joined: 10 Mar 2015
Posts: 23

View user's profile Send private message

Big problem with simple math operation
PostPosted: Tue May 19, 2015 1:24 pm     Reply with quote

Hi everybody!
I used pic18f6722 and 20x4 lcd with flexible driver
I have a big problem with few math operation, and variables;
Maybe sounds funny or/and stupid but I crazy because is not working fine;
I have first, second, and third number which is int8 and is between 0-255; and result which is long and is big number > 4 000 000 000
but when I used
first = 200;
second = 200;
result = first + second --> and result is not 400, but is 144
result = first * second --> and result is not 40 000, but is between 0-255

I want to calculate:
result = first + (second * 100) + (third * 60 * 100);

How can I fix this problem.

main.c
Code:

#include "main.h"
#fuses NOXINST
#use delay(clock=32000000)
#include <flex_lcd.c>

void main()
{
   int8 first, second, third;
   long result;
   
   setup_oscillator(OSC_32MHZ);
   delay_ms(100);
   lcd_init();
   delay_ms(100);
   
   
   first = read_eeprom(0x55);
   second = read_eeprom(0x56);
   third = read_eeprom(0x57);
   result = first + (second * 100) + (third * 60 * 100);
   lcd_gotoxy(1, 1);
   printf(lcd_putc, "R: %u %u %u = %ld", first, second, third, result); //Display R: 255 255 255 = 43
   
   first = 200;
   second = 200;
   result = first + second;
   lcd_gotoxy(1, 2);
   printf(lcd_putc, "F: %u + %u = %ld", first, second, result); //Display F: 200 + 200 = 144
   
   first = read_eeprom(0x55);
   second = 100;
   result = first + second;
   lcd_gotoxy(1, 3);
   printf(lcd_putc, "S: %u + %u = %ld", first, second, result); //Display S: 200 + 100 = 99
   
   write_eeprom(0x55, 200);
   first = read_eeprom(0x55);
   second = 100;
   result = first + second;
   lcd_gotoxy(1, 4);
   printf(lcd_putc, "T: %u + %u = %ld", first, second, result); //Display T: 200 + 100 = 44
}


main.h
Code:

#include <18F6722.h>
#device adc=12

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

#use delay(clock=32000000)


My version of CCS C Compiler is 4.057.
best regard evelikov92
jeremiah



Joined: 20 Jul 2010
Posts: 1342

View user's profile Send private message

PostPosted: Tue May 19, 2015 2:05 pm     Reply with quote

you need to do some casting.

When you have:
Code:

unsigned int8 A = 200;
unsigned int8 B = 200;
unsigned int32 C;

C = A + B;


Since both A and B are int8 sized variables, their result has to be int8. Remember the compiler isn't going to up convert for you. So the process for your original code is:

unsigned int8 value + unsigned int8 value = unsigned int8 value;
unsigned int32 value = (unsigned int32)unsigned int8 value;

Which isn't the process you were aiming for.

If you want the actual addition result to be the same size as C you need to cast either A or B to unsigned int32:

Code:

unsigned int8 A = 200;
unsigned int8 B = 200;
unsigned int32 C;

C = A + (unsigned int32)B;


That'll force the compiler to cast A to an unsigned int32 to match B and the result will be unsigned int32.

The same applies to multiplication, you need one of the params to be the size of the result (via casting) so that the math gets converted to the size you want.

C = ((unsigned int32)A)*200 + B;

for example.

EDIT: Also avoid using non specific types like int and long. Stick to sized types like int8, int16, etc.
evelikov92



Joined: 10 Mar 2015
Posts: 23

View user's profile Send private message

PostPosted: Wed May 20, 2015 12:11 am     Reply with quote

It's working. Thanks for fast answer jeremiah.
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